iOS-Objective-C内存管理
内存管理:
栈区 [stack]:由编译器自动分配并释放,一般存放函数的参数值,局部变量等
堆区 [heap]:由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收
全局区(静态区) [static]:全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域,程序结束后由系统释放
文字常量区:存放常量字符串,程序结束后由系统释放
程序代码区:存放函数的二进制代码
官方文档:
在iOS开发中:
一. 内存分析
1. 静态分析(Analyze)
不运行程序, 直接检测代码中是否有潜在的内存问题(不一定百分百准确, 仅仅是提供建议)
结合实际情况来分析, 是否真的有内存问题
2. 动态分析(Profile == Instruments)
1> 运行程序, 通过使用app, 查看内存的分配情况(Allocations)
* 可以查看做出了某个操作后(比如点击了某个按钮\显示了某个控制器), 内存是否有暴增的情况(突然变化)
2> 运行程序, 通过使用app, 查看是否有内存泄漏(Leaks)
* 红色区域代表内存泄漏出现的地方
二. 内存使用注意
1. 加载小图片\使用频率比较高的图片
1> 利用imageNamed:方法加载过的图片, 永远有缓存, 这个缓存是由系统管理的, 无法通过代码销毁缓存
2. 加载大图片\使用频率比较低的图片(一次性的图片, 比如版本新特性的图片)
1> 利用initWithContentsOfFile:\imageWithContentsOfFile:\imageWithData:等方法加载过的图片, 没有缓存, 只要用完了, 就会自动销毁
2> 基本上, 除imageNamed:方法以外, 其他加载图片的方式, 都没有缓存
PS:--关于图片资源
1> 会压缩到Assets.car文件, 没有直接暴露在沙盒的资源包(main Bundle)
* 条件 : "Deployment Target >= 7.x" 并且是 "放在Images.xcassets里面的所有图片"
* 影响 : 无法得到图片的全路径, 只能通过图片名(imageNamed:方法)来加载图片, 永远会有缓存
2> 不会压缩到Assets.car文件, 直接暴露在沙盒的资源包(main Bundle)
* 条件 : 除1> 以外的所有情况
* 影响 : 可以得到图片的全路径, 可以通过全路径(imageWithContentsOfFile:方法)来加载图片, 不会有缓存
三. 如何让程序尽量减少内存泄漏
1. 非ARC--MRC
* Foundation对象(OC对象) :
只要方法中包含了alloc\new\copy\mutableCopy\retain等关键字,
那么这些方法产生的对象, 就必须在不再使用的时候调用1次release或者1次autorelease
* CoreFoundation对象(C对象) :
只要函数中包含了create\new\copy\retain等关键字,
那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数
2. ARC(只自动管理OC对象, 不会自动管理C语言对象)
* CoreFoundation对象(C对象) :
只要函数中包含了create\new\copy\retain等关键字, 那么这些方法产生的对象, 就必须在不再使用的时候调用1次CFRelease或者其他release函数
* 利用__bridge桥接,告诉编译器 管理c语言对象。
3. block的注意--见:block详解!
// block的内存默认在栈里面(系统自动管理) void (^test)() = ^{ };
// 如果对block进行了Copy操作, block的内存会迁移到堆里面(需要通过代码管理内存) Block_copy(test);
// 在不需要使用block的时候, 应该做1次release操作 Block_release(test); [test release];
--------------------
栈:由系统自动分配 --由系统自动分配,速度较快 [ FIFO ]
栈区结构:链表 or 数组
栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域,栈顶的地址和栈的最大容量是系统预先规定好的,在 iOS中,主线程栈的大小是1M
--[ 栈区:申请内存后响应 ]
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出
--存储的内容
栈:变量名(不带*)相当于是指向栈区数据的指针别名,变量名可以简化程序员的工作
--------------------
堆:需要程序员自己申请,alloc,copy --是由alloc分配的内存,速度比较慢,而且容易产生内存碎片,不过用起来最方便 [ LIFO ]
堆区结构:树 or 链表
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大
--[ 堆区:申请内存后响应 ]
堆:
1. 操作系统有一个记录空闲内存地址的链表
2. 当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序
3. 由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中
--存储的内容
堆:要访问堆区中的数据,必须通过指针的方式才可以进行,指针的类型决定了访问堆中数据的方式
--堆区的操作!
1、操作系统以匿名(只记录内存地址和大小,不记录具体类型)的方式记录已经分配的内存区域
2、当某一内存区域不再使用时,程序需要通知操作系统回收该内存区域,从而可以保证该内存区域被其他程序再次使用,否则,该区域将永远无法被再次分配,这就是传说中的“内存泄露”
3、如果某一区域已经被释放,仍然视图访问该区域,会提示“坏内存访问”,这就是传说中的“野指针访问”
--------------------
总结:
1、我们程序员只需要关心堆区的内存管理,而栈区系统会自动回收。
2、栈区存放的局部变量,出了作用域就会被销毁!
3、内存结构中的其他几个分区,跟程序同生死:程序启动时,被加载到内存中;程序摧毁,内存被回收!
PS:在iOS开发中:
1> 堆区的内存是所有应用程序共享的,问题:内存泄露 & 野指针
|--> 内存泄漏:如果程序员使用变量后,不释放内存(有强指针指向它),该内存区域会永远被占有,别的Application无法使用,即内存警告
|--> 内存溢出(Out Of Memory):内存不够使用了,数据长度比较小的数据类型 存储了 数据长度比较大的数据类型
|--> 野指针:当对象已经释放,程序中变量的指针,依然指向该内存地址,如果再向该对象发送消息,就会报“野指针”错误
2> 堆区的内存分配是由系统负责的。
3> 系统是使用一个链表来维护所有已经分配过的内存空间。(见:上边--堆区:申请内存后响应)
4> 系统只是记录分配了多少字节给应用程序,并不管理具体的类型-->“匿名”:只是记录分配的内存大小,不管具体是哪个类的!
5> 如果变量使用结束后,需要释放内存,OC中当一个变量的引用计数==0时,说明没有变量使用这块内存空间,即系统直接回收。
-------
分享:
数据结构&算法分析 PDF,下载:Download !
-----------
|--> Copyright (c) 2015 Bing Ma.
|--> GitHub RUL: https://github.com/SpongeBob-GitHub
iOS-Objective-C内存管理的更多相关文章
- IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- IOS开发小记-内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- iOS夯实:内存管理
iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...
- Objective C内存管理之理解autorelease------面试题
Objective C内存管理之理解autorelease Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的A ...
- [转载]对iOS开发中内存管理的一点总结与理解
对iOS开发中内存管理的一点总结与理解 做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...
- iOS开发ARC内存管理技术要点
本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...
- iOS MRC ARC 内存管理
转自:http://www.jianshu.com/p/48665652e4e4 1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用 ...
- iOS开发ARC内存管理
本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...
- iOS另类的内存管理
iOS的内存管理算是老生常谈的问题了,我们写iOS的时候无时无刻不在涉及到内存管理.从开始的MRR(manual retain-release)到后来ARC(Automatic Reference C ...
- IOS开发之内存管理--dealloc该写些什么
在非ARC开发环境中,dealloc是类释放前,清理内存的最后机会.到底那些变量和属性该释放呢,一些特殊的类(nstimer,observer)该怎么释放.需要注意的是不释放会引起内存泄露,过度释放也 ...
随机推荐
- __attribute__((packed))详解
1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法.这个功能是跟操作系统没关系,跟编译器有关 ...
- easyconf——基于AugularJS的配置管理系统开发框架
目录 1 easyconf的诞生2 easyconf的设计理念 2.1 总体设计 2.2 细节设计 2.2.1 CRUD操作 2.2.2 即时校验 2.2.3 下拉框设计3 easyconf使用指南 ...
- 【解题报告】BZOJ2550: [Ctsc2004]公式编辑器
题意:给定一个可视化计算器的操作序列,包括插入数字.字母.运算符.分数.矩阵以及移动光标.矩阵插入行.插入列,输出操作序列结束后的屏显(数学输出). 解法:这题既可以用来提升OI/ACM写大代码模拟题 ...
- 使用 AForge.NET 做视频采集
AForge.NET 是基于C#设计的,在计算机视觉和人工智能方向拥有很强大功能的框架.btw... it's an open source framework. 附上官网地址: http://www ...
- <Oracle Database>物理结构
物理结构 Oracle物理结构包含了数据文件.日志文件和控制文件 数据文件 每一个Oracle数据库有一个或多个物理的数据文件.一个数据库的数据文件包含全部数据库数据.数据文件有下列特征: 一个数据文 ...
- swift的运算符
1.什么是运算符?它有什么作用? 运算符是一种特定的符号或者表达式.它用来验证.修改.合并变量. 2.运算符有哪些? 运算符有很多,很多朋友学的很烦.这里我依据它的作用把它分为几块来介绍: a:赋值运 ...
- Eclipse中设置jsp文字大小
- android 编译代码注意事项
1 安装openjdk1.7 sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-apt update sudo apt-get install op ...
- XML dom
将文件解析为文档 三步过程 为了使用 XML 文件中的信息,必须解析文件以创建一个 Document 对象. Document 对象是一个接口,因而不能直接将它实例化:一般情况下,应用程序会相应使用一 ...
- Python学习笔记1——Python基础
一. 数据类型和变量 整数:十六进制用0x前缀和0-9,a-f表示 浮点数:小数,科学计数法:10用e代替:整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(包括除法),浮点数运算则可 ...