数据在内存中的存放
在计算机系统中,运行的应用程序的数据都是保存在内存之中。
不同类型的数据,保存的内存区域不同,其中包括:
1.栈区:(stack)由编译器自动分配并释放,一般存放函数的参数值,局部变量等。
2.堆区:(heap)由程序猿分配和释放,如果程序猿不释放,程序结束时,可能由操作系统回收。
3.寄存器区:用来保存栈顶指针和指令指针。
4.全局区(静态区):全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放。
5.文字常量区:存放常量字符串,程序结束后由系统释放。
6.程序代码区:存放函数的二进制代码。
栈区中的数据
应用程序启动后,操作系统会为应用程序在栈区开辟内存空间,用于存放局部变量,以及函数的参数等。
iOS主线程栈区大小为1M,MAC主线程栈区大小为8M.
栈区中的变量由编译器负责分配和释放。
栈区中的数据是以“栈”的形式管理的,先进后出(FIBO)。
访问栈区中变量的效率高,不会出现内存碎片。
栈区中的变量名(不带*)相当于是指向栈区数据的指针别名,变量名可以简化程序员的工作。
栈中地址是从高地址——>低地址。
堆中的数据
由于栈区的空间有限,iOS的应用程序中,对象都是建立在堆中的。
堆区包括系统内存和虚拟内存(硬盘内存),由所有正在运行的应用程序共享使用。
堆区中的内存分配由操作系统使用一个链表统一维护所有已经分配的内存记录。
由于堆区是由所有应用程序共享的,操作系统以匿名(只记录内存地址和大小,不记录具体类型)的方式记录已经分配的内存区域。
要访问堆区中的数据,必须通过指针的方式才可以进行,指针的类型决定了访问堆中数据的方式。
当某一内存区域不再使用时,程序需要通知操作系统回收该区域内存,从而可以保证该内存区域被其它程序再次使用,否则,该区域将永远无法再次被分配,这就是传说中的“内存泄露”。
如果某一区域已经被释放,仍然试图访问该区域,会提示“坏内存访问”,这就是传说中的“野指针访问”。
相比较栈区,堆区中的效率要低很多,同时容易出现内存碎片。
相比较栈区,堆区中的访问方式更加灵活,对象占用的内存也可以更大。