在计算机系统中,运行的应用程序的数据都是保存在内存中的,不同类型的数据,保存的内存区域不同:
栈区(stack) 由编译器自动分配并释放,一般存放函数的参数值,局部变量等
堆区(heap) 由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收
全局区(静态区) (static) 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放
文字常量区 存放常量字符串,程序结束后由系统释放
程序代码区 存放函数的二进制代码
申请大小的限制:
栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域,栈顶的地址和栈的最大容量是系统预先规定好的,在 iOS中,主线程栈的大小是1M
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大
申请效率:
栈:由系统自动分配,速度较快
堆:是由alloc分配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便
存储内容:
栈:变量名(不带*)相当于是指向栈区数据的指针别名,变量名可以简化程序员的工作
堆:要访问堆区中的数据,必须通过指针的方式才可以进行,指针的类型决定了访问堆中数据的方式
操作系统以匿名(只记录内存地址和大小,不记录具体类型)的方式记录已经分配的内存区域
当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则,该区域将永远无法被再次分配,这就是传说中的“内存泄露”
如果某一区域已经被释放,仍然视图访问该区域,会提示“坏内存访问”,这就是传说中的“野指针访问”
栈区(stack) 由编译器自动分配并释放,一般存放函数的参数值,局部变量等
堆区(heap) 由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收
全局区(静态区) (static) 全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放
文字常量区 存放常量字符串,程序结束后由系统释放
程序代码区 存放函数的二进制代码
申请大小的限制:
栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域,栈顶的地址和栈的最大容量是系统预先规定好的,在 iOS中,主线程栈的大小是1M
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大
申请效率:
栈:由系统自动分配,速度较快
堆:是由alloc分配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便
存储内容:
栈:变量名(不带*)相当于是指向栈区数据的指针别名,变量名可以简化程序员的工作
堆:要访问堆区中的数据,必须通过指针的方式才可以进行,指针的类型决定了访问堆中数据的方式
操作系统以匿名(只记录内存地址和大小,不记录具体类型)的方式记录已经分配的内存区域
当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则,该区域将永远无法被再次分配,这就是传说中的“内存泄露”
如果某一区域已经被释放,仍然视图访问该区域,会提示“坏内存访问”,这就是传说中的“野指针访问”