南宁网站开发培训,学校网站模板免费下载,上海专业网站优化排名,前端网站开发参考文章 要想了解什么是VM Regions#xff0c;就得先了解什么是虚拟内存。当我们向系统申请内存时#xff0c;系统并不会给你返回物理内存的地址#xff0c;而是给你一个虚拟内存地址。每个进程都拥有相同大小的虚拟地址空间#xff0c;对于32位的进程#xff0c;可以拥有…参考文章 要想了解什么是VM Regions就得先了解什么是虚拟内存。当我们向系统申请内存时系统并不会给你返回物理内存的地址而是给你一个虚拟内存地址。每个进程都拥有相同大小的虚拟地址空间对于32位的进程可以拥有4GB的虚拟内存64位进程则更多可达16EB。只有我们开始使用申请到的虚拟内存时系统才会将虚拟地址映射到物理地址上从而让程序使用真实的物理内存。下面是一个简易示意图 进程A和B都拥有1到4的虚拟内存。系统通过虚拟内存到物理内存的映射让A和B都可以使用到物理内存。上图中物理内存是充足的但是如果A占用了大部分内存B想要使用物理内存的时候物理内存却不够该怎么办呢在OSX上系统会将不活跃的内存块写入硬盘一般称之为swapping out。iOS上则会通知App让App清理内存也就是我们熟知的Memory Warning。
堆区会被划分成很多不同的VM Region不同类型的内存分配根据需求进入不同的VM Region。除了MALLOC_MEDIUM和MALLOC_SMALL外还有MALLOC_TINYMALLOC_LAEGE MALLOC metadata等等。
VM Region Size:
我们在VM Track中可以看到一个VM Region有4种size。
Dirty Size Swapped Size Resident Size Virtual Size Virtual Size顾名思义就是虚拟内存大小将一个VM Region的结束地址减去起始地址就是这个值。Resident Size指的是实际使用物理内存的大小。Swapped Size则是交换到硬盘上的大小仅OSX可用。Dirty Size根据官方的解释我的理解是如果一个内存页想要被复用必须将内容写到硬盘上的话这个内存页就是Dirty的。下面是官方对Dirty Size的解释。secondary storage可以理解为硬盘。
malloc 和 calloc:
我们除了使用NSObject的alloc分配内存外还可以使用c的函数malloc进行内存分配。malloc的内存分配当然也是先分配虚拟内存然后使用的时候再映射到物理内存不过malloc有一个缺陷必须配合memset将内存区中所有的值设置为0。这样就导致了一个问题malloc出一块内存区域时系统并没有分配物理内存。然而调用memset后系统将会把malloc出的所有虚拟内存关联到物理内存上因为你访问了所有内存区域。我们通过代码来验证一下。在main方法中创建一个1024*1024的内存块也就是1M。
malloc_zone_t 和 NSZone
相信大家对NSZone并不陌生allocWithZone或者copyWithZone这2个方法大家应该也经常见到。那么Zone究竟是什么呢Zone可以被理解为一组内存块在某个Zone里分配的内存块会随着这个Zone的销毁而销毁所以Zone可以加速大量小内存块的集体销毁。不过NSZone实际上已经被苹果抛弃。你可以创建自己的NSZone然后使用allocWithZone将你的OC对象在这个NSZone上分配但是你的对象还是会被分配在默认的NSZone里。例如 static NSMutableSet *objs nil;if (objs nil) { objs [NSMutableSet new]; }NSZone *testZone NSCreateZone(1024, 1024, YES);NSSetZoneName(testZone, Test Object Zone);for (int i 0; i 1000; i) {TestObject *obj [TestObject allocWithZone:testZone];[objs addObject:obj];}代码创建了1000个TestObject对象但是最后其实都在系统默认床架的NSZone中Test Object Zone中只有1个node其中是用来存放Zone本身的信息的如果你真的想用Zone内存机制可以使用malloc_zone_t。通过下面的代码可以在自定义的zone上malloc内存块例如 malloc_zone_t *testZone malloc_create_zone(1024, 0);malloc_set_zone_name(testZone, Test malloc zone);for (int i 0; i 1000; i) {malloc_zone_malloc(testZone, 300 * 4096);}最后运行的结果是我们的Test malloc zone中有1001个node也就是1000个Test_zone_malloc出来的内存块加上zone本身的信息所占的内存块。
另外我们可以使用malloc_destroy_zone(testZone)一次性释放上面分配的所有内存。