iOS程序内存分配

iOS程序所占的内存分区

  • 栈区:

    • 存放函数的参数值,局部变量的值,基本数据类型等
    • 由编译器自动分配释放,不需要程序猿管理栈内存
    • 存放的数据变量遵循先进后出,且栈地址是从高到低分配
  • 堆区:

    • OC中用alloc函数生成的对象都是放在堆区
    • 堆区的内存一般由程序猿进行释放,如果不释放,程序运行结束后由系统进行回收
    • 堆区存放数据遵循先进先出,地址是从低到高
  • 全局区/静态区(static):

    • 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,
      未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,
    • 程序结束后由系统进行释放
    • eg:int a;未初始化的。int a = 10;已初始化的
  • 常量区:

    • 常量字符串就是放在这里的。 程序结束后由系统释放
  • 代码区:

    • 存放函数体的二进制代码

代码示例讲述

这是一个前辈写的,非常详细 

//main.cpp 
int a = 0; 全局初始化区 
char *p1; 全局未初始化区 
main() 
{ 
int b; 栈 
char s[] = "abc"; 栈 
char *p2; 栈 
char *p3 = "123456"; 123456\0在常量区,p3在栈上。 
static int c =0; 全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得来得10和20字节的区域就在堆区。 
strcpy(p1, "123456"); 123456\0放在常量区。 
}

如下图所示:代码区存放于低地址,栈区存放于高地址,且区与区之间并不是连续的


image

注意事项:

  • 在iOS中,堆区的内存是应用程序共享的,而堆区的内存分配是由系统负责的
  • 当一个app启动后,代码区,常量区,全局区大小已固定,因此指向这些区的指针不会产
    生崩溃性的错误。而堆区和栈区是时时刻刻变化的(堆的创建销毁,栈的弹入弹出),所
    以当使用一个指针指向这两个区里面的内存时,一定要注意内存是否已经被释放,否则会
    产生程序崩溃(也即是野指针报错)

堆区和栈区的比较

1.按照管理方式:

  • 栈:系统编译器管理,不需要程序猿管理
  • 堆:释放工作由程序员手动管理,不及时回收容易产生内存泄露

2.按照分配方式:

  • 栈:静态分配和动态分配
    • 静态分配:静态分配是系统编译器完成的,比如局部变量的分配
    • 动态分配:动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,它
      的动态分配也由系统编译进行释放,不需要程序员手动管理
  • 堆:堆是动态分配和回收内存的,没有静态分配的堆

堆区的一个例子

创建一个新的对象时,对象p指针存放在栈区,p将指向在堆区开辟的一块存储空间Person


image

在程序结束之前,p对象必须release,不然系统不知道释放堆区的Person内存。

如果p对象没有release,只是p=nil; 就是p指针指向了堆区地址为0的地方,那么原来的Person永远无法再次访问,而且也无法释放掉。

堆是所有程序共享的内存,当N个这样的内存得不到释放,堆区会被挤爆,程序立马瘫痪。这就是内存泄漏。

参考①:http://www.cnblogs.com/hangdada/p/4982989.html

参考②:http://www.tuicool.com/articles/RbA3imB

参考③:http://my.oschina.net/jlongtian/blog/596698

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容