iOS 堆和栈的区别?
前言
堆和栈是什么?有什么区别?是干嘛的?啥东西呀这是?别急,慢慢看下去
内存管理
移动设备的内存及其有限,每一个APP所能占用的内存是有限制的
(吐槽一下:iPhone6s还是16G起步,还好我也买不起->_-> 扯远了~~~)
什么行为会增加APP的内存占用
- 创建一个oc对象
- 定义一个变量
- 调用一个函数或者方法
内存管理范围
- 任何继承了NSObject的对象
- 对其它非对象类型无效
- 简单来说:
- 只有oc对象需要进行内存管理
- 非oc对象类型比如基本数据类型不需要进行内存管理
引入堆和栈的概念
- 所以问题就来了,为什么OC对象需要进行内存管理,而其它非对象类型比如基本数据类型就不需要进行内存管理呢?
- 只有OC对象才需要进行内存管理的本质原因?
因为:
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,就是release
OC对象存放于堆里面(堆内存要程序员手动回收)
非OC对象一般放在栈里面(栈内存会被系统自动回收)
堆里面的内存是动态分配的,所以也就需要程序员手动的去添加内存、回收内存
举例说明
该代码块在内存中的表现形式如下图
图中可以看到,栈里面存放的是非对象的基本数据类型,堆内存存放着oc对象
当代码块一过,里面的a,b,*c指针都会被系统编译器自动回收,因为它存放在栈里面,而OC对象则不会被系统回收,因为它存放堆里面,堆里面的内存是动态存储的,所以需要程序员手动回收内存
总结区别
- 按管理方式分
- 对于栈来讲,是由系统编译器自动管理,不需要程序员手动管理
- 对于堆来讲,释放工作由程序员手动管理,不及时回收容易产生内存泄露
- 按分配方式分
- 堆是动态分配和回收内存的,没有静态分配的堆
- 栈有两种分配方式:静态分配和动态分配
- 静态分配是系统编译器完成的,比如局部变量的分配
- 动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,它的动态分配也由系统编译器进行释放,不需要程序员手动管理
一位网友用10个字总结了堆和栈的区别
栈是吃了吐 堆是吃了拉
·············································································································································································································································································
iOS 内存基础知识及堆区和栈区的区别
iOS内存区域大致分为;栈区,堆区,全局区(静态区),文字常量区,程序代码区
栈区
- 栈区(stack)由编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系统数据结构,对应线程/进程是唯一的。优点是快速高效,缺点是有限制,数据不灵活。(先进后出)
alloc在堆上申请一块空间返回一个指针,这个指针在栈上,申请的空间在堆上
这里指的局部变量不是对象地址,而是这个对象的指针在栈上
- 申请后的系统响应, 栈区存储每一个函数在执行的时候都会向操作系统所要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束释放,由系统自动完成
只要栈的剩余空间大于所申请空间,系统讲为程序提供内存,否则将报异常提示栈溢出
申请大小的限制
栈是向低地址扩展的数据结构,是一块连续的内存的区域。是栈顶的地址和栈的最小容量是系统预先规定好的,栈的大小是2M(也有的说是1M,总之是一个编译时就却确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小栈由系统自动分配,速度较快,以内栈是先进后出的队列,他们时如此的一一对应,以至于永远都不可能有一个内存快从栈中间弹出,不会产生内存碎片
堆区
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表
堆是一种特殊的树形数据结构,每个节点都有一个值。通常我们所说的堆的数据结构,是指二叉树。堆的特点是根节点的值最小(或最大),且根节点的两个子树也是一个堆
堆分为大根堆,小根堆,大根堆就是树的根结点大于叶子节点。
- 堆区(heap)由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收,比如iOS种alloc都是存放在堆中
优点是灵活方便,数据适应面广泛,但是效率又一定降低
堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存和释放时优质程序开发者的必备的素质
- 堆区申请后的系统响应
首先应该知道操作系统会有一个记录空闲内存地址的链表
当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲结点链表中删除,并将该结点的空间分配给程序
由于找到的堆接点大小不一定正好等于申请的大小,系统会自动将多余的那部分重新放入到空闲链表中
3.申请大小的限制
堆向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的。而链表的便利方向是从低地址向高地址的。堆的大小受限于计算机系统中的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大
4.频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率最低,不过用起来最方便
全局区(静态区)(static)
全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域。程序结束后有系统释放
文字常量区
存放常量字符串,程序结束后由系统四方
程序代码区
存放函数的二进制代码
内存分配地址
栈区
- 栈区的内存地址是从高到低的分配
- 栈区存放局部变量,先进后出,一旦出了作用域就会被销毁
堆区
- 堆区的内存地址是从低到高分配
- 堆区的变量空间分配都是alloc,程序员需要管理堆区的内存
- ARC的内存管理,是在编辑器编译的时候,自动添加retain等,c的变量的内存管理,需要程序员处理
- 堆区的内存由所有应用程序共享
- 堆区的内存分配由系统来负责
- 系统使用一个链表来维护所有已经分配过的内容空间
字符串内存管理
NSString是以恶搞不可变的字符串对象。这不是表示这个对象生命的变量的值不可变,而是表示它初始化之后,你就不能改变该变量所分配的内存中的值,但你可以重新分配该变量所处的内存空间。copy和retain对他都是浅复制,也就是单纯的指针复制
浅拷贝和深拷贝
浅拷贝,只是拷贝了对象的指针,而不是拷贝对象本事。深拷贝,是直接拷贝整个对象的内存到另一快内存中
- 浅拷贝(shallow copy):在浅拷贝操作的时候,对于被拷贝对象的每一层都是指针拷贝
- 单层拷贝(one-level-deep copy):在深拷贝操作时,对于被拷贝对象,至少又一层是深拷贝
- 深拷贝(real-deep copy):在完全拷贝操作是,对于被拷贝对象的每一层都是对象拷贝
集合的深拷贝
NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];
归档一个容器类对象(archive)拷贝后,然后解档(unarchive),即可实现里面元素的深拷贝
在容器类对象中,对immutable对象进行copy,是指针拷贝,mutableCopy是内容拷贝;对mutable对象进行copy和mutableCopy都是内容拷贝。但是:集合对象的内容拷贝仅限于对象本身,对象元素仍然是指针拷贝。
iOS 堆和栈的区别?相关推荐
- 黑马程序员——堆和栈的区别(转载)
------ Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 转自:http://www.cnblogs.com/Kevin_z/archive/2010/ ...
- 堆和栈的区别(面试经验总结)
C++中,内存分为5个区:堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区.通常存放局部变量.函数参数等. 堆:是由new分配的内存块, ...
- 堆和栈的区别 (转贴)
非本人作也!因非常经典,所以收归旗下,与众人阅之!原作者不祥! 堆和栈的区别 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动 ...
- mysql中堆和栈_堆和栈的区别
在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的.JVM运行时在内存中开辟一片内存 ...
- (009) java后台开发之堆和栈的区别
转自:https://course.tianmaying.com/java-basic+object-usage# 堆和栈的区别 堆和栈都是Java中常用的存储结构,都是内存中存放数据的地方: 1.在 ...
- 什么是堆和栈以及区别详解
堆 先进先出 存取速度慢 存储数组和对象 动态分配内存 都是实体 栈 先进后出 存取速度快 存储变量 什么是堆内存? 它的作用是用于存储java中的对象和数组 当我们new一个对象或者创建一个数组的时 ...
- 语言堆栈入门——堆和栈的区别
原文:http://student.csdn.net/link.php?url=http://www.top-e.org%2Fjiaoshi%2Fhtml%2F427.html 格式和部分内容稍作修改 ...
- 堆 和 栈的 区别(经典)
堆和栈的区别 一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 操作方式 ...
- 内存中“堆”和“栈”的区别
内存中"堆"和"栈"的区别: 程序中用来存放数据的内存分为四块,分别是: 1.全局区(静态区)(static):全局变量和静态变量都存储在这块区域,与其他变量的 ...
最新文章
- WEB测试—用户界面测试
- SpringCloud微服务注册中心如何承载大型系统的千万级访问?源码及原理分析
- 一个超乎想象的垃圾收集器:ZGC
- Integer你真的了解吗,快来瞅瞅吧
- 024、JVM实战总结:动手实验:线上部署系统时,如何设置垃圾回收相关参数?
- 【阿圆总结】关于平时阅读的推荐
- python教程视频哪个好-Python 基础视频教程那个好?
- Mac端将本地新项目上传到github
- C中define的#和##
- Java中文乱码详解
- javascript 代码转换为 typescript 代码
- java基础学习_集合类04_Map接口、Collections工具类_day18总结
- 关于智能家居,一篇绝对中立的详细指南及各类问题解答
- 41.Android之图片放大缩小学习
- CAD文件版本怎么转换?如何将高版本转换成低版本?
- Stream流式计算
- CSS实现圆角,三角,五角星,五边形,爱心,12角星,8角星,圆,椭圆,圆圈,八卦等等
- 国外知名乐队都在用的社交媒体二维码
- AD7799称重系统
- 2019寒假安排计划
热门文章
- 南自动化计算机控制实验报告,东南大学计算机控制实验报告一.docx
- 差分约束入门题ZOJ2770AOJ517
- BDP FL-PEG4-TCO,BDP FL-四聚乙二醇-(4E)-反式环辛烯​,CAS:2183473-16-5
- 信息技术学业水平考试 上机考试 16题 windows操作题(10分);
- 计算机软件的教学设计,计算机软件教学设计
- 思维导图 进阶(03)链接 高效记忆,理解与记忆同在
- RBW VBW-解析带宽与视频带宽(转)
- HashTab基于链表简单实现(java,不包含扩容)
- 《麻省理工科技评论》Emtech China峰会召开,全球顶级科技大脑揭示将改变世界的新兴科技...
- 判断访问WEB的平台是电脑还是手机