JHHK

欢迎来到我的个人网站
行者常至 为者常成

内存分布

目录

内存分布

一 内存分布图如下

img

二 分段说明

text段:

代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。

这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。

data段:

数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。

数据段属于静态内存分配。

bss段:

bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。

bss是英文Block Started by Symbol的简称。

bss段属于静态内存分配。

堆(heap):

堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。

当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);

当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

栈(stack):

是用户存放程序临时创建的局部变量,

也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中

三 注意

1 text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;

2 bss段不在可执行文件中,由系统初始化,清0操作。

3 包含data段和bss段的整个区段此时通常称为数据区

//代码片段一
int ar[30000];
void main(){
    ......
}
//代码片段二
int ar[300000] = {1, 2, 3, 4, 5, 6 };
void main(){
    ......
}

片段二的可执行文件远远大于片段一的可执行文件

代码演示

int  a = 1;
- (IBAction)memoryLayout:(id)sender {
    //常量区(.data)
    //a:  0x100fdb4dc 1
    NSLog(@"a:  %p %d",&a,a);
}


- (IBAction)memoryLayout1:(id)sender {
    //常量区(.data)
    //b:  0x100fdb4e0 2
    static int b = 2;
    NSLog(@"b:  %p %d",&b,b);
    b = 3;
}


int c;
- (IBAction)memoryLayout2:(id)sender {
    //静态区(.bss)
    //c:  0x102bee154 0
    NSLog(@"c:  %p %d",&c,c);
}


- (IBAction)memoryLayout3:(id)sender {
    //静态区(.bss)
    //d:  0x102beb858 0
    static int d;
    NSLog(@"d:  %p %d",&d,d);
}



- (IBAction)memoryLayout4:(id)sender {
    //变量e  常量区(.data)
    //字符串 常量区(.data)
    //e:  0x1044bf508 0x1044625f0
    static NSString * e = @"abcdefghijklmnopqrstuvw";
    NSLog(@"e:  %p %p",&e,e);
    
    
    //变量f  栈区(.stack)
    //字符串 常量区(.data)
    //f:  0x16bd2cf50 0x1044625f0
    NSString * f = @"abcdefghijklmnopqrstuvw";
    NSLog(@"f:  %p %p",&f,f);
    
    
    //变量g  栈区(.stack)
    //字符串 常量区(.data)
    //g:  0x16bd2cf48 0x1044625f0
    NSString * g = [[NSString alloc]
                    initWithString:@"abcdefghijklmnopqrstuvw"];
    NSLog(@"g:  %p %p",&g,g);
    
    
    //变量h  栈区(.stack)
    //字符串 堆区(.heap)
    //h:  0x16bd2cf40 0x281afb720
    NSString * h = [[NSString alloc]
                    initWithFormat:@"%@",@"abcdefghijklmnopqrstuvw"];
    NSLog(@"h:  %p %p",&h,h);
}

关于static的的演示

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
static int memoryNum = 100;
@interface MemoryObject : NSObject

- (void)testOne;
- (void)testTwo;
@end

NS_ASSUME_NONNULL_END


#import "MemoryObject.h"

@implementation MemoryObject


- (void)testOne {
    memoryNum++;
    NSLog(@"testOne:memoryNum %d",memoryNum);
}

- (void)testTwo {
    memoryNum++;
    NSLog(@"testTwo:memoryNum %d",memoryNum);
}

@end

#import "MemoryObject.h"

NS_ASSUME_NONNULL_BEGIN

@interface MemoryObject (one)
- (void)testThree;
@end

NS_ASSUME_NONNULL_END

#import "MemoryObject+one.h"

@implementation MemoryObject (one)
- (void)testThree {
    memoryNum++;
    NSLog(@"testThree:memoryNum %d",memoryNum);
}
@end

- (IBAction)memoryLayout5:(id)sender {
    NSLog(@"外部:memoryNum %d",memoryNum);//外部:memoryNum 100
    memoryNum = 1000;
    NSLog(@"外部:memoryNum %d",memoryNum);//外部:memoryNum 1000

    MemoryObject * obj = [[MemoryObject alloc] init];
    [obj testOne];//testOne:memoryNum 101
    [obj testTwo];//testTwo:memoryNum 102
    NSLog(@"外部:memoryNum %d",memoryNum);//外部:memoryNum 1000
    
    [obj testThree];//testThree:memoryNum 101
    NSLog(@"外部:memoryNum %d",memoryNum);//外部:memoryNum 1000
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.