1. 内存结构

219 阅读3分钟

一、内存区域图

71265735b2c14a0691b9fb135a7c61b1.png

  • Stack(栈): 局部变量和函数运行过程中的上下文
  • Heap(堆): 存储所有对象
  • Global: 存储全局变量;常量;代码区
    1. TEXT.text : 机器码
    2. TEXT.cstring : 硬编码的字符串
    3. TEXT.const: 初始化过的常量
    4. DATA.data: 初始化过的可变的(静态/全局)数据
    5. DATA.const: 没有初始化过的常量
    6. DATA.bss: 没有初始化的(静态/全局)变量
    7. DATA.common: 没有初始化过的符号

二、各区域作用

  1. 栈区(Stack)— 由编译器自动分配释放 ,空间申请速度较快,主要存放函数的参数值,局部变量的值等。栈是向低地址扩展的数据结构,是一块连续的内存的区域。如果申请的空间超过栈的剩余空间时,将会出现栈溢出。因 此,能从栈获得的空间较小。
  2. 堆(Heap):堆由程序员主动申请空间并管理(管理不好会出现内存泄漏),申请速度低于栈,它是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
  3. 全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。
  4. 常量区:常量字符串就是放在这里的,程序结束后由系统释放。
  5. 代码区:存放函数体的二进制代码。

三、测试

  1. 安装LLDB调试插件-libfooplugin.dylib
// 创建 .lldbinit 文件
$ vim ~/.lldbinit

// 输入内容并保存
plugin load <libfooplugin.dylib绝对路径>

// Demo中lldb调试命令
cat address <内存地址>
  1. 测试代码
// main.m

#import <Foundation/Foundation.h>

// *p1 TEXT.cstring
char *p1 = "123456";
// &p2 TEXT.const
const char p2 = '0';
// &p3 DATA.data
static char p3 = '1';
// &p4 DATA.bss
static char p4;
// &p5 DATA.common
char p5;

int main() {
    // &p6 stack
    char *p6;
    // *p7 Heap:
    char *p7 = (char *)malloc(10);
	  // 此处断点调试
    printf(p1, p2, p3, p4, p5, p6, p7);
    return  0;;
}
  1. 调试日志
(lldb) p p1
(char *) $0 = 0x0000000100003fb0 "123456"
(lldb) cat address 0x0000000100003fb0
address:0x0000000100003fb0, 0TestDemo.__TEXT.__cstring +0

(lldb) p &p2
(const char *) $2 = 0x0000000100003fb7 "0\x01"
(lldb) cat address 0x0000000100003fb7
address:0x0000000100003fb7, 0p2 <+0> , External: NO TestDemo.__TEXT.__const +0

(lldb) p &p3
(char *) $4 = 0x0000000100008020 "1"
(lldb) cat address 0x0000000100008020
address:0x0000000100008020, 10p3 <+0> , External: NO TestDemo.__DATA.__data +10

(lldb) p &p4
(char *) $10 = 0x0000000100008021 <no value available>
(lldb) cat address 0x0000000100008021
address:0x0000000100008021, 0p4 <+0> , External: NO TestDemo.__DATA.__bss +0

(lldb) p &p5
(char *) $11 = 0x0000000100008022 <no value available>
(lldb) cat address 0x0000000100008022
address:0x0000000100008022, 0p5 <+0> , External: NO TestDemo.__DATA.__common +0


(lldb) p &p6
(char **) $12 = 0x00007ffeefbff550
(lldb) cat address 0x00007ffeefbff550
address:0x00007ffeefbff550, stack address (SP: 0x7ffeefbff530 FP: 0x7ffeefbff560) main


(lldb) p p7
(char *) $14 = 0x00000001007addc0 ""
(lldb) cat address 0x00000001007addc0
address:0x00000001007addc0, (String) $R15 = "0x1007addc0 heap pointer, (0x10 bytes), zone: 0x7fff99eca000"