E-moss,程序员,爱好阅读和撸狗,主要从事iOS开发工做,公众号:知本集。
主要分享和编写技术方面文章,不按期分享读书笔记,亦可访问“知本集”Git地址:https://github.com/knowtheroot/KnowTheRoot_iOS,欢迎提出问题和讨论。
复制代码
Git地址:github.com/knowtheroot…git
当咱们向系统申请内存时,系统并不会直接返回物理内存的地址,而是返回一个虚拟内存地址。从系统角度来讲,每个进程都有相同大小的虚拟内存空间。
只有当进程开始使用申请到的虚拟内存时,系统才会将虚拟地址映射到物理地址上,从而让程序使用真实的物理内存。程序员
当A进程占用了大部份内存,此时B进程须要内存时发现内存不足,系统则会通知App,让App清理内存,既咱们熟知的Memory Warning。github
虚拟内存也有一样的缺点:硬盘的容量比内存大,但也只是相对的,速度却很是缓慢,若是和硬盘之间的数据交换过于频繁,处理速度就会降低,表面上看起来就像卡住了同样,这种现象称为抖动(Thrushing)。相信不少人都有过计算机中止响应的经历,而形成死机的主要缘由之一就是抖动。bash
iOS系统会对虚拟内存和物理内存进行分页,虚拟内存到物理内存的映射都是以页为最小粒度的。数据结构
将虚拟内存空间和物理内存空间皆划分为大小相同的页面,如4kb、8kb或16kb等。并以页面做为内存空间的最小单位,一个程序的一个页面能够存放在任意一个物理页面里。ide
系统将内存页分为三个状态:
(1)活跃的内存页(active page):内存页已经被映射到物理内存中,并且近期被访问过,处于活跃状态。
(2)非活跃的内存页(inactive page):内存页已经被映射到物理内存中,可是近期没有被访问过。
(3)可用的内存页(free page):没有关联到虚拟内存页的物理内存页集合。函数
当可用的内存页下降到必定的阀值时,系统就会采起低内存应对措施,在OSX中,系统会将非活跃内存页交换到硬盘上,而在iOS中,则会触发Memory Warning,若是你的App没有处理低内存警告而且还在后台占用太多内存,则有可能被杀掉。优化
页表的功能是提供虚拟页面到物理页面的映射。
页表的记录条数与虚拟页面数相同。此外,内存管理单元依赖于页表来进行一切与页面有关的管理活动,这些活动包括判断某一页面号是否在内存里,页面是否受到保护,页面是否非法空间等等。
因为页表的特殊地位,决定了它是由硬件直接提供支持,即页表是一个硬件数据结构。spa
为了更好的管理内存页,系统将一组连续的内存页关联到一个VMObject上。
VMObject主要包含如下属性:指针
堆区会被划分红不少不一样的VM Region,不一样类型的内存分配根据需求进入不一样的VM Region。
OC中,除了使用NSObject的alloc分配内存外,还可使用c的函数malloc进行内存分配。malloc的内存分配固然也是先分配虚拟内存,而后使用的时候再映射到物理内存,不过malloc有一个缺陷,必须配合memset将内存区中全部的值设置为0。这样就致使了一个问题,malloc出一块内存区域时,系统并无分配物理内存。然而,调用memset后,系统将会把malloc出的全部虚拟内存关联到物理内存上,由于你访问了全部内存区域。
为了解决这个问题,苹果官方推荐使用calloc代替malloc,calloc返回的内存区域会自动清零,并且只有使用时才会关联到物理内存并清零。
calloc和malloc 主要的区别在于前者在返回内存的指针以前将它初始化为0,另外它们请求数量的方式不一样。calloc的参数包括所需元素的数量和每一个元素的字节,根据这些值能够计算出总共须要分配的内存空间(num_elements*element_size)个字节。