
作为一个学计算机专业毕业的人,被面试官问到:你是学计算机的吧,那你说说栈与堆的区别?我当时的脑子里基本上是想不到怎么说,因为真的没仔细研究过这两者的详细区别,当时只是说:
虽然回答的也不算错,但这是很片面的回答。
所以回来后我决定再仔细复习一下这方面的知识。于是就有了这篇文章。
首先总结起来堆与栈的区别主要有以下几点:
内存管理的5大区域:
栈(stack)和堆(heap)都是内存区域的其中两种形式,我们称为栈区和堆区。
栈区 是由编译器自动管理的,其 *** 作方式是 后进先出(LIFO) ,当我们运行一个方法时,方法的参数、方法中的局部变量都会被自动存储在栈区中,当出了作用域后(方法运行结束),这些参数和局部变量就会被释放。
-应用中新创建的每个线程都有专用的栈空间。
堆区 则由程序员进行分配和释放,例如:
对应的栈和堆空间的分配过程:
当创建一个对象时会在堆内存中开辟一块内存空间并进行初始化,并给对象分配了一个唯一的内存地址。创建的局部变量存储在栈中,其通过内存地址引用堆中的对象,我们也称array是一个指针,它指向的是堆中的某个对象。当发送release消息时(MRC)或作用域结束栈中的指针被释放后(ARC),对象会被释放,堆中的这块内存区域也就被释放被系统回收了。由于需要我们手动控制,所以要非常注意避免出现内存泄漏。
-每个进程的所有线程共享一个堆。
内存泄漏的主要由以下两点造成的:
在MRC,我们如果将array = nil,而没有[array release];那么导致指针没了,堆中的对象还存在,但无法再被引用,就造成了内存泄漏。
在ARC,当方法结束后,栈中的array被编译器自动释放,就没有指针指向堆中的该对象了,编译器就会自动插入调用release回收该对象,因而不会导致内存泄漏。
简单地说,栈是属于进程管理的,大小相对固定,规模较小,一旦 *** 作系统为程序分配了栈后就不管了, *** 作系统将其看做进程的一部分,栈的性质是先进后出,后进先出;堆属于系统维护的,进程可以申请的额外内存空间,访问方式是自由的(相对于栈的先进后出)。稍微深入点说,栈是由系统在加载程序时给进程分配的一块区域,提供存放栈数据,一般定义的变量都会存在栈区,函数调用以及数据传递和返回、递归、嵌套循环,文件夹等树状层次结构的遍历、表达式的解析都会用到栈区。栈的大小由编译器决定,也可以在IDE(集成开发环境,比如VC,VS,VB或任何编程工具)中设定,编译好的程序包含了栈空间大小的参数,当被 *** 作系统加载时由 *** 作系统一起分配给程序。当程序结束时栈区与进程空间一起被回收释放。所以,如果定义的数据超过栈的空间程序就会发生溢出而崩溃,编译器不负责检查,因此大容量数据不要分配在栈上。在C++中,应该使用new关键词,用new分配的对象或内存都是在堆上,堆是系统维护的内存空间,也可理解为 *** 作系统中看到的未使用的空间,当执行new的时候就是程序向 *** 作系统申请额外空间,因此new也叫动态分配内存。系统会根据需求大小从未使用的空间中划一块给程序使用,并对该空间进行注册管理,以便当程序结束时释放该空间(假如程序没有主动申请释放)。所以用new创建的空间在使用完了后要及时申请释放(delete关键词),如果不释放,在程序运行期间如果不断的new大内存,最终也会将整个可用内存用完,导致系统崩溃,当然,如今的 *** 作系统比以前强壮得多,当发生内存用完导致崩溃时, *** 作系统会干预,直接down掉程序禁止运行下去并回收所有所占空间。
以上就是关于聊聊iOS开发中堆与栈的区别全部的内容,包括:聊聊iOS开发中堆与栈的区别、内存分配中堆和栈的区各是指什么、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)