内存管理:

栈区 [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

栈 & 堆 |--> 内存管理的更多相关文章

  1. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

  2. Linux堆内存管理深入分析

    (上半部) 作者:走位@阿里聚安全 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞利用两种.国内关于栈溢出的资料相对较 ...

  3. C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针

    C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...

  4. Linux堆内存管理深入分析 (上半部)【转】

    转自:http://www.cnblogs.com/alisecurity/p/5486458.html Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全 0 前言 近年来,漏洞挖掘越来 ...

  5. Linux堆内存管理深入分析(下)

     Linux堆内存管理深入分析 (下半部) 作者@走位,阿里聚安全 0 前言回顾 在上一篇文章中(链接见文章底部),详细介绍了堆内存管理中涉及到的基本概念以及相互关系,同时也着重介绍了堆中chunk分 ...

  6. C 堆内存管理

    在Win32 程序中每个进程都占有4GB的虚拟地址空间,这4G的地址空间内部又被分为代码段,全局变量段堆段和栈段,栈内存由函数使用,用来存储函数内部的局部变量,而堆是由程序员自己申请与释放的,系统在管 ...

  7. Dalvik 堆内存管理与回收

    Dalvik虚拟机用来分配对象的堆划分为两部分,一部分叫做Active Heap,另一部分叫做Zygote Heap.下面基于管理机制来介绍为何分配为这两部分,以及堆内存的管理. 我们从Android ...

  8. Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解

    C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...

  9. javascript中的栈堆内存

    <--------栈内存---------> 俗称叫做作用域(全局作用域/私有作用域) >为js代码提供的执行环境(执行js代码的地方) >基本数据内省是直接存放在栈内存中的 ...

随机推荐

  1. 你的第一个AngularJS应用--教程二:基架、建立和測试的工具

    介绍 有非常多可用的工具能够帮助你开发AngularJS 应用,那些非常复杂的框架不在我的讨论范围之中,这也是我開始这系列教程的原因. 在第一部分,我们掌握了AngularJS框架的基本结构,开发了第 ...

  2. 猪和python(pig and python)

    Python 真是无处不在国内. pig 0.9后python作为嵌入式语音,采用Jython解释器使用python2.5特征,此接口是最上层org.apache.pig.scripting.Pig首 ...

  3. webpack打包avalon

    webpack打包avalon+oniui+jquery 随着avalon的发展壮大,我根据CSDN的统计数字,中国前端大概有1%的人在使用avalon了. avalon的最大优势是能兼容IE6,并且 ...

  4. 使用JavaScript检测浏览器

    假设你真的需要检测浏览器的类型,使用JavaScript非常easy达到. View Demo Download Source from GitHub JavaScript有一个navigator的标 ...

  5. LeetCode——Pascal&#39;s Triangle

    Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Retu ...

  6. NET版微信客户端.

    微信客户端.NET版 目录 说明 功能 原理步骤 一些参考 说明 前两天比较闲,研究了一下web版微信.因为之前看过一篇博客讲微信web协议的,后来尝试分析了一下,半途中发现其实没什么意义,但又不想半 ...

  7. Cocos2d-Java安装和配置跨平台游戏引擎以及相关的开发工具

    假设认为博文图片不清晰.能够Ctrl+鼠标滚动缩放网页比例 Cocos2d-Java是什么? http://blog.csdn.net/touchsnow/article/details/387047 ...

  8. Codeforces Round #256 (Div. 2)——Multiplication Table

    题目链接 题意: n*m的一个乘法表,从小到大排序后,输出第k个数  (1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m) 分析: 对于k之前的数,排名小于k:k之后的数大于,那么就能够採用 ...

  9. nginx 提供静态内容

    Serving Static Content 提供静态内容 原文地址:http://nginx.com/resources/admin-guide/serving-static-content/ Th ...

  10. 新版本NDK环境结构(避Cygwin,超快)

    曾经做Android的项目要用到NDK就必需要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量... 麻烦到不想说 ...