在iOS中,大家平常经常说堆区,栈区,其实这些都是存在虚拟内存。 虚拟内存可以主要分为五个大区(堆区、栈区、全局区、常量区、代码区)。
一、堆区(heap)
由程序员分配释放,分配方式类似于链表,是向高地址扩展的数据结构,是不连续的内存区域。用于存放进程运行中被动态分配的内存段,堆区的大小并不固定,可动态扩张或缩减。当进程调用 alloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张),当利用 realse 释放内存时,被释放的内存从堆中被剔除(堆被缩减)。如果应用程序没有释放掉,程序结束,操作系统会自动回收。变量通过new 、alloc 、malloc 、realloc 分配的内存块就存放在堆区。 堆向高地址扩展的数据结构,是不连续的内存区域。程序员负责在何时释放内存,在ARC程序中,计数器为0的时候,在当次的runloop 结束后,释放掉内存。堆中的所有东西都是匿名的,这样不能按名字访问,而只能通过指针访问。 对于堆来讲,频繁的new /delete 势必会造成内存空间的不连续性,从而造成大量的碎片 ,使程序效率降低。
二、栈区(stack)
又称堆栈 ,由编译器自动分配释放,是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}” 中定义的变量(但不包括 static 声明的变量, static 意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于 栈的后进先出特点,所以栈特别方便用来保存 /恢复 调用现场。从这个意义上讲,我们可以把堆栈 看成一个寄存、交换临时数据的内存区。
三、全局区(静态区)( bss segment )
- 全局/静态区是存放全局变量和静态变量的。
- 已初始化的全局变量和静态变量存放在一块区域。
- 未初始化的全局变量和静态变量在相邻的另一块区域。
- 由 static 修饰的变量会成为静态变量,该变量的内存由全局/静态区在编译阶段完成分配,且仅分配一次。
- static 可以修饰局部变量也可以修饰全局变量。
全局/静态区 的内存在编译阶段完成分配,程序运行时会一直存在内存中,只有当程序结束后才会由操作系统释放。
四、常量区(data segment)
- 是编译时分配的内存空间,在程序结束后由系统释放。存放的是常量,是一块特殊的区域
- 通常是指用来存放程序中已经初始化的全局变量和静态变量的一块内存区域。数据段属于静态内存分配,可以分为只读数据段和读写数据段。字符串常量等,是放在只读数据段中,结束程序时才会被收回。
五、代码区
代码区 是用来存放可执行文件的操作指令(存放函数的二进制代码),其实就是存放程序的所有代码。代码区 需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作:它是不可写的。
|