【iOS】源碼閱讀(三)——內存對齊原理

文章目錄

  • 前言
  • 獲取內存大小的三種常用方式
    • sizeof
    • class_getInstanceSize
    • malloc_size
  • 總結

前言

??之前學習alloc相關源碼,涉及到內存對齊的相關內容,今天筆者詳細學習了一下相關內容并寫了此篇博客。

獲取內存大小的三種常用方式

??獲取內存大小的方式有很多種,主要分為三類:獲取對象實例占用的內存大小、獲取進程占用的內存大小??、獲取數據結構/內存塊的大小?。在iOS中獲取內存大小的三種方式主要有:sizeof 、class_getInstanceSize 、malloc_size。

sizeof

  • 編譯時運算符??,返回變量或類型在內存中占用的字節數。
  • ??只適用于??基本數據類型(int、float)、結構體、類實例(僅計算靜態分配的內存)。
  • 不適用于動態分配的內存(如通過 malloc 分配的部分)、對象頭(如 Objective-C 的 isa 指針)。

??首先,需要明確,sizeof是一個操作數,不是函數;其次,這個大小在編譯時就已經確定了,不考慮運行時的動態內存。對于OC對象,sizeof只返回指針的大小(通常情況下為8字節),而不是對象的實際占用內存。

在這里插入圖片描述

在這里插入圖片描述
%zu:

一般用于輸出或讀取 size_t 類型(即無符號整型)的變量(通常是 sizeof 運算符的結果)。

class_getInstanceSize

  • Objective-C 運行時函數??,返回一個 Objective-C 類的實例對象在內存中占用的實際大小(不包括額外的 malloc 分配開銷)。
  • ??包含的內容:isa 指針(8 字節),所有實例變量(ivars)的大小,內存對齊填充。
#import <objc/runtime.h>@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name; // 8 字節
@property (nonatomic, assign) NSInteger age;  // 8 字節
@end@implementation MyClass
@end// 計算實例變量總大小
size_t instanceSize = class_getInstanceSize([MyClass class]);
NSLog(@"實例變量大小: %zu 字節", instanceSize); 

請添加圖片描述
按理論來說,這里應該輸出16個字節,但實際上輸出為24個字節,這是為什么呢?
這里可以簡單理解為class_getInstanceSize 遵循的是8字節對齊:

每個 Objective-C 對象都有一個 isa 指針,指向它的類對象,這在 64 位系統上占用 8 字節。
在剛剛的代碼中:
NSString *name:一個強引用的指針,占用 8 字節
NSInteger age:在 64 位系統上占用 8 字節

所以剛才代碼中的內存計算:isa (8) + name (8) + age (8) = 24 字節

所以總和是 24 字節(8 + 8 + 8),這正好是 8 字節對齊的倍數,不需要額外填充。如果這個類沒有聲明任何實例變量,大小會是 16 字節(8 字節的 isa 指針 + 8 字節的填充,以滿足最小 16 字節的對象大小要求)。

至于為什么類沒有聲明任何實例變量,大小會是 16 字節:

isa 指針占用 8 字節(所有 Objective-C 對象都有)。
Objective-C 運行時強制對象最小大小為 16 字節(即使沒有實例變量),這是為了內存管理的效率(減少小對象的內存碎片)。剩余的 8 字節是 填充(padding),未被使用但必須分配。

總結:

class_getInstanceSize遵循8字節對齊。
24 字節 是 isa + name + age 的自然大小,不需要額外填充。
類沒有聲明任何實例變量,大小會是 16 字節。

malloc_size

  • ??C 標準庫函數??,返回 malloc(或 calloc/realloc)實際分配的內存塊大小(可能比請求的大小更大),遵循16字節對齊。
  • 包含??對象本身的大小(class_getInstanceSize 的結果)和 malloc 的內存管理開銷(如內存對齊、內存池優化等)。
int *array = malloc(10 * sizeof(int)); // 請求40字節
size_t allocatedSize = malloc_size(array);
printf("Malloc size: %zu\n", allocatedSize); // 輸出為48(16字節對齊)

請添加圖片描述
了解到這里,我們就可以把 class_getInstanceSize和malloc_size拉在一起看看,我們在剛剛 class_getInstanceSize學習的代碼里添加:

size_t allocatedSize = malloc_size((__bridge const void *)obj);
NSLog(@"malloc_size: %zu", allocatedSize); // 32

這里會輸出32,因為class_getInstanceSize 計算的是 24 字節,但 malloc 會 向上取整到最近的 16/32 字節,所以實際分配 32 字節:
請添加圖片描述

總結

??先用代碼來進行對比,我們可以看到輸出結果:
在這里插入圖片描述
在這里插入圖片描述
??對三者進行總結如下:
請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80143.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80143.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80143.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

新手學編程前端好還是后端

在當今數字化的時代&#xff0c;編程成為了一項備受追捧的技能。對于那些剛剛踏入編程世界的新手來說&#xff0c;常常會面臨一個重要的抉擇&#xff1a;是選擇前端開發&#xff0c;還是后端開發&#xff1f;這就像是站在一個分岔路口&#xff0c;每一條路都充滿了未知和機遇。…

【面試 · 一】vue大集合

目錄 vue2 基礎屬性 組件通信 全局狀態管理 vueX 路由 路由守衛 vue3 基礎屬性 組件通信 全局狀態管理 Pinia 路由 路由守衛 vue2、vue3生命周期 setup vue2 基礎屬性 data&#xff1a;用于定義組件的初始數據&#xff0c;必須是一個函數&#xff0c;返回一個對…

nginx之proxy_redirect應用

一、功能說明 proxy_redirect 是 Nginx 反向代理中用于修改后端返回的響應頭中 Location 和 Refresh 字段的核心指令&#xff0c;主要解決以下問題&#xff1a;協議/地址透傳錯誤&#xff1a;當后端返回的 Location 包含內部 IP、HTTP 協議或非標準端口時&#xff0c;需修正為…

[Qt] mvd使用的注意事項

在使用mvd時&#xff0c;我們可能會有這種需求&#xff0c;比如有一項的數據是文件類型&#xff0c;然后我們要彈出一個文件對話框&#xff0c;選擇一個文件路徑然后把文件路徑展示出來。 我們可能寫出如下代碼 #include "MyStyledItemDeletegate.h" #include <Q…

LeetCode 220 存在重復元素 III 題解

LeetCode 220 存在重復元素 III 題解 題目描述 給定一個整數數組 nums 和兩個整數 k 和 t&#xff0c;請判斷數組中是否存在兩個不同的索引 i 和 j&#xff0c;使得&#xff1a; abs(nums[i] - nums[j]) < tabs(i - j) < k 方法思路&#xff1a;桶排序 滑動窗口 核…

路由器詳細講解

目錄 一、路由器的定義和基本功能 二、路由器的分類 三、路由器的工作原理 四、路由器的配置 五、路由器的選購要點 路由器是一種網絡設備&#xff0c;它在計算機網絡中扮演著至關重要的角色&#xff0c;主要用于連接不同的網絡&#xff0c;并根據數據包的目的地址選擇合適…

Spring MVC @CookieValue 注解怎么用?

CookieValue 注解的作用 CookieValue 注解用于將 HTTP 請求中特定 Cookie 的值綁定到 Controller 方法的參數上。 Cookies 是由服務器發送到用戶瀏覽器并保存在本地的一小塊數據。瀏覽器在后續向同一服務器發送請求時&#xff0c;會通過 Cookie 請求頭將這些數據再帶回給服務…

控制mac地址表端口安全

一、端口安全的核心理論 安全MAC地址類型 安全動態MAC&#xff1a;啟用端口安全后動態學習的MAC地址&#xff0c;設備重啟后丟失&#xff0c;需重新學習。 安全靜態MAC&#xff1a;手動配置的MAC地址&#xff0c;永久生效且不會被老化。 Sticky MAC&#xff1a;動態學習后自動…

【wpf】10 C#樹形控件高效實現:遞歸構建與路徑查找優化詳解

在WPF應用程序開發中&#xff0c;樹形控件的實現是常見且具有挑戰性的需求。本文將深入解析一套高效樹形結構的實現方案&#xff0c;包含遞歸構建、路徑查找優化、動態交互等多個關鍵技術點。 一、遞歸構建樹形結構 private TreeItem CreateTreeViewItem(TreeNode node) {var…

面向未來的 TCP 協議設計:可擴展與兼容并存

目錄 1.設計思路 &#xff08;1&#xff09;完整數據結構&#xff08;字節布局&#xff09; 1&#xff09;字段解釋&#xff1a; 2&#xff09;Flags字段設計&#xff08;1字節位圖&#xff09; &#xff08;2&#xff09;進階版 Java 解碼器實現&#xff08;示例&#xf…

MCP 入門指南

文章來源&#xff1a;https://anmolbaranwal.com/ 本文涵蓋內容如下&#xff1a; 現有AI工具的問題。MCP及其核心組件介紹。MCP 內部是如何工作的&#xff1f;MCP 解決的問題以及它為何重要。MCP 的 3 個層&#xff08;以及我最終如何理解它們&#xff09;。使用內置 Auth 連接…

第 14 屆藍橋杯 C++ 青少組省賽中 / 高級組真題解析

一、選擇題 第 1 題 題目&#xff1a;C 中&#xff0c;bool 類型的變量占用字節數為&#xff08; &#xff09;。 A. 1 B. 2 C. 3 D. 4 答案&#xff1a;A 解析&#xff1a; C 標準規定&#xff0c;bool類型至少占用 1 字節&#xff08;1 byte&#xff09;&#xff0c;用于存…

使用 Selenium 爬取動態網頁數據 —— 實戰與坑點詳解

本文記錄了筆者在爬取網頁數據過程中遇到的各種技術挑戰&#xff0c;包括頁面動態渲染、JavaScript 注入等問題&#xff0c;并最終給出一個可運行的完整方案。 文章目錄 網頁獲取不到數據&#x1f680; 嘗試用 Selenium 渲染頁面 網頁獲取不到數據 某網頁數據依賴大量 JavaSc…

【信息系統項目管理師】法律法規與標準規范——歷年考題(2024年-2020年)

手機端瀏覽?【信息系統項目管理師】法律法規與標準規范——歷年考題&#xff08;2024年-2020年&#xff09; 2024年上半年綜合知識【占比分值3′】 42、關于招標投標的描述&#xff0c;不正確的是&#xff08;屬于同一集團組織成員的投標人可以按照該組織要求協同投標&#xf…

多模態大語言模型arxiv論文略讀(五十六)

DesignQA: A Multimodal Benchmark for Evaluating Large Language Models’ Understanding of Engineering Documentation ?? 論文標題&#xff1a;DesignQA: A Multimodal Benchmark for Evaluating Large Language Models’ Understanding of Engineering Documentation …

Docker 渡渡鳥鏡像同步站 使用教程

Docker 渡渡鳥鏡像同步站 使用教程 &#x1f680; 介紹 Docker.aityp.com&#xff08;渡渡鳥鏡像同步站&#xff09;是一個專注于為國內開發者提供 Docker 鏡像加速和同步服務的平臺。它通過同步官方鏡像源&#xff08;如 Docker Hub、GCR、GHCR 等&#xff09;&#xff0c;為…

Unity:AddTorque()(增加旋轉力矩)

目錄 什么是 AddTorque()&#xff1f; 第一性原理出發&#xff1a;什么是 Torque&#xff08;力矩&#xff09;&#xff1f; Torque 公式 Unity 中 AddTorque 的工作原理 參數屬性 &#x1f50d; Linear Drag&#xff08;線性阻力&#xff09; 線性阻力模擬的現實情況&…

async/await的另一種食用方法

在JavaScript/TypeScript的異步編程中&#xff0c;async/await讓我們的代碼看起來更像是同步的&#xff0c;極大地提高了可讀性。然而&#xff0c;錯誤處理仍然是一個需要仔細考慮的問題。今天我要分享一種優雅的錯誤處理模式&#xff0c;它能讓你的異步代碼更加簡潔。 傳統tr…

計算機網絡 - stp生成樹實驗

【實驗假設】 我們使用 Cisco Packet Tracer 或類似的模擬軟件&#xff0c;或物理的 Cisco 交換機。 交換機初始為默認配置&#xff08;或已通過 write erase 和 reload 清除配置&#xff09;。 PC 已配置 IP 地址如下&#xff08;示例&#xff09;&#xff1a; PC0: 192.168…

淺析 Spring 中 FactoryBean 的實現與使用

淺析 Spring 中 FactoryBean 的實現與使用 一、FactoryBean核心機制剖析二、高級應用場景與實戰三、框架級應用案例解析四、FactoryBean常見面試題 一、FactoryBean核心機制剖析 1. 本質與雙重角色 FactoryBean是Spring容器中用于定制化對象創建的核心接口&#xff08;org.spri…