1.iOS内存分区

说到内存,我们一般会讲到RAM和ROM,RAM与ROM就是具体的存储空间,统称为存储器。

  • RAM(random access memory):运行内存,CPU可以直接访问,读写速度非常快,但是不能掉电存储,例如内存条。
  • ROM(read only memory):存储性内存,可以掉电存储,例如SD卡、Flash(机械磁盘也可以简单的理解为ROM)。

内存分区

说到内存分区,这里的内存指的就是RAM(random access memory)
内存分为五个区:栈区(系统管理的地方)、堆区(程序员控制的地方)、静态区(全局区)常量区代码区

1、栈区(stack): 由编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系统数据结构,对应线程/进程是唯一的。

  • 快速高效,但是有限制,数据不灵活。[先进后出]
  • 栈空间分:静态分配动态分配两种。
  • 静态分配是编译器完成的,比如自动变量(auto)的分配。
  • 动态分配由alloca函数完成。
  • 栈的动态分配无需释放(是自动的),也就没有释放函数。
  • 为可移植的程序起见,栈的动态分配操作是不被鼓励的!

2、堆区(heap):由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收 ,比如变量通过new、alloc、malloc、realloc分配的内存块就存放在堆区。

  • 灵活方便,数据适应面广泛,但是效率有一定降低。[顺序随意]
  • 堆是函数库内部数据结构,不一定唯一。
  • 不同堆分配的内存无法互相操作。
  • 堆空间的分配总是动态的
  • 虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存,释放内存匹配是良好程序的基本要素。

3、全局区(静态区) (static): 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放。

注意:全局区又可分为未初始化全局区(BSS段)和初始化全局区(DATA段)。
举例:int a;未初始化的;int a = 10;已初始化的。

4、文字常量区: 存放常量字符串,程序结束后由系统释放

5、程序代码区: 存放函数的二进制代码

#import "ViewController.h"

@interface ViewController ()

@end

//age存放在<未初始化的全局静态区(BSS区)>
NSInteger age;
 
//age存放在<已初始化的全局静态区(DATA区)>
NSInteger score = 100;
 
//@"SunSatan"存放在<常量区>,name存放在<已初始化的全局静态区>
NSString *name = @"SunSatan";
 
//titleStr存放在<已初始化的全局静态区>
static NSString *titleStr = @"SunSatan";

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    int flag;//flag存放在<栈区>
    NSString *number = @"8090";//number存放在<栈区>
    
    //array_1、array_2存放在<堆区>
    NSArray *array_1 = [[NSArray alloc]init];
    NSArray *array_2 = [NSArray array];
    
    //array_3存放在<栈区>
    NSArray *array_3 =@[];
    
    //total存放在<栈区>
    NSInteger total = [self getTotalNumber:1 number2:1];
}

- (NSInteger)getTotalNumber:(NSInteger)number1 number2:(NSInteger)number2{
    return number1 + number2;//number1和number2 栈区
}

@end

总结:

  • 在编译阶段代码区、常量区、全局/静态区就已经分配完成并且大小固定,所以指向这些区的指针不会产生崩溃性的错误。
  • 栈区和堆区内存分配随着程序运行而变化(堆的创建销毁,栈的弹入弹出)。
    • 栈:由系统自动分配,速度较快,不会产生内存碎片 [先进后出]
    • 堆:由程序员通过alloc等函数申请的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便

打个比喻来说:

  • 使用栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
  • 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

你可能感兴趣的:(1.iOS内存分区)