在进行性能优化之前我们先补充几个概念,方便后续更好的理解性能优化。
RAM和ROM
RAM:属于系统运行时内存,具有读取速度快、能和CPU进行数据交换的优点,但是不具备掉电存储的能力(一断电数据就没了)。
ROM:属于存储性内存,具有掉电存储的能力,无法直接与CPU进行数据交换。
所以在启动一个App时,系统会把App拷贝到RAM。
内存分区
内存分区.png如上图所示,内存分为内核区、栈区、堆区、全局区(未初始化数据、已初始化数据区)、代码区、保留区。
1、内核区:主要是处理内核模块,比如我们的系统内存为4GB,那么我们实际上能使用3GB,剩下的1GB就是给了内核区,指针地址0xc0000000(310241024*1024)
2、栈区(stack):栈区里面会放一些函数参数以及一些局部变量,逐渐增多并在内存地址中由高向低延伸,由于栈的数据结构的原因,它的内存地址是连续的,栈区的内存大小在App启动时就确定下来的,若在压入时申请的内存空间大于栈的剩余空间,就会出现栈溢出(内存泄露),打印的地址为0x7在栈区
3、堆区(heap):堆区里面存放着alloc或new出来的变量,会逐渐增多并在内存地址中由低向高延伸,系统是用链表来管理堆的内存的,所以它的内存地址不是连续的,堆的内存大小是动态变化的,它确定于系统的虚拟内存,所以堆的内存一般较大,打印的地址为0x6的在堆区
4、全局区/静态区:未初始化数据bss段和已初始化数据data段
5、常量区:存放一些常量字符串,程序结束后由系统自动释放
6、代码段(.text):我们的程序在编译完成后都会到代码段中去执行
7、保留区:用来给系统提供一些必要空间
举个例子来理解一下:
1、对象查找过程:
在程序查找一个对象时,首先到栈区找到对象的指针,再通过这个对象指针到堆区找到这个对象。
2、栈溢出
while (10000) {
int a = 2;
}
上面这段代码会造成内存暴涨,因为栈区只有1M大小,一个int类型是4字节,创建一个局部变量就会压入一个4字节到栈区,当超过栈区的上限时就会造成栈溢出。
网友评论