当前位置:编程学习 > wap >>

程序员详解iOS的原生和第三方虚拟内存机制

虚拟内存。这项技术本质上就是对内存地址进行映射,使得进程认为自己拥有连续的,大量的内存,提高内存利用率,降低程序编写难度。因此,虚拟内存范畴可以划分为两类:第一类:将进程占用的内存地址映射到RAM内其他位置,第二类:将进程占用的内存地址映射到磁盘上面。iOS5必定是有第一类虚拟内存的,但没有第二类。
 
首先介绍一下虚拟内存。这项技术本质上就是对内存地址进行映射,使得进程认为自己拥有连续的,大量的内存,提高内存利用率,降低程序编写难度。比如一个程序被系统告知其可用的内存片段是0到100页。而实际上其占用的内存片段可能是分散的,有可能其占用的真正物理范围是70-120页,201页到240页,还有10页在磁盘上面。
 
因此,虚拟内存范畴可以划分为两类:
第一类:将进程占用的内存地址映射到RAM内其他位置。
第二类:将进程占用的内存地址映射到磁盘上面。
而我们通俗讲的虚拟内存就是第二类。
 
第一类由于都是在RAM内进行的,速度很快,并且有专门硬件负责转换,因而就像是把宾馆房间的门牌号换一下而已,对程序的执行没有任何影响。
 
第二类由于磁盘的速度读写速度太慢,且很多都会有一定读写次数的限制,因此,当在磁盘上的页面要被使用时候,并非直接在磁盘上修改,而是重新搬运回RAM并暂时冻结进程,搬运完成后在RAM内被修改。而RAM内不活动的页面也会在内存不足时候搬运到磁盘上,为活动的进程提供可用的物理内存。也就是说,磁盘相当于一个仓库而已,真正干活的地方还是在RAM里面。
这种方式使得在一些小内存的机器上也可以运行一些占用内存大程序,但是不足之处就是慢,卡。
 
iOS5必定是有第一类虚拟内存的,但是没有第二类。
 
首先,如果使用虚拟内存,必定会造成一定的慢,卡,大家在PC上内存满时候应该体会过。而这一点正是苹果所不愿意的。苹果一定要让一项技术可以流畅的在设备上运行时候才让它出现。这个很好理解,多任务就是这样的。
 
其次,设备会在内存不足时候自动关掉一些后台程序,如果使用了这项技术,就不会出现内存不足的情况,一旦内存不足,系统会自动将一些不活动进程在内存里数据搬到磁盘里,为活动的程序提供空间,因而也就是说所有的程序都会在后台保留,最终虚拟内存占用的磁盘空间也会越来越大。而事实上并没有这种情况。而苹果本身的设计也就是允许用户不去关闭这些后台程序。
当然,你也可以认为iOS的虚拟内存不会提供给应用程序使用。但是如果真的这样,这虚拟内存又有什么用呢?
 
除此之外,苹果也在发布会后的一次WWDC大会上说了:limited memory/virtual memory/no swapfile。也就是说并没有通俗意义上的虚拟内存。
 
至于一些开发者发现在terminal里面输入top时候有一个VM的数值,并怀疑它是虚拟内存大小。那个具体是什么我也不知道,但是我认为并不是的。那个数值确实会随着程序开的越多而越大,甚至可以到达4G。
 
下面是我分析的办法。我将用户盘和系统盘全部塞满,发现系统仍然可以正常运行。当我打开那些程序的时候,VM的数值同样增大,最终同样可以到4G以上。那这部分空间是在什么地方呢?假如你说是在除系统盘和用户盘以外的地方,好的,这不是不可能,但我们可以算一下。我是32G的,用户盘大小29754M,系统盘大小1024M,加起来30778M也就是30G,那剩下的4G往什么地方塞?况且一般来讲由于换算原因和其它因素实际可用空间都会小于称标空间的。
 
至于iOS系统的内存管理究竟是怎么样的呢?据我推测是这样的。
 
①当内存不足时候,首先会先叫后台程序或者系统进程释放。此时后台程序会主动释放一些不太重要的数据资料,比如说图片信息之类的,保留最重要的状态信息,与此同时也可能对内存数据进行压缩。此时,由于占用处理器资源,可能会出现卡顿。
 
②当内存依然不足时,系统便开始考虑关闭一些后台程序了。此时,后台程序会得到信号,然后开始运行,进行数据的保存,完成后退出,释放内存。此时,由于会占用处理器以及储存器,可能会再次导致卡顿。
 
③如果问题还不能得到解决,系统就会强制结束前台程序,同时在/var/logs/AppleSupport/下面留下一堆lowmemory的错误报告。这就是常说的闪退的一种原因。
 
由此也可以说明,iOS系统的内存管理确实很先进,确实是没有必要去关闭后台程序。当然,如果你认为①②步骤导致的小卡让你很不爽,那你还是主动去关吧。
 
说完了iOS系统的内存管理,下面来说一下用deb安装的虚拟内存,也就是真正意义上的虚拟内存。
 
有人说开启这种虚拟内存完全没有用,只能是使得内存看上去增大了很多而实际上没有任何用,还会导致系统不稳。
 
而我想在此澄清的是:
 
①虚拟内存并不能增大你设备的内存,只是为正在运行的程序腾出空间。
 
打个比方,就是虚拟内存并不能增大你工作间的面积,但是它给你提供了一个仓库,可以将一些当前没有用的东西搬进去放着,这样你就可以拥有更多空间干你正在干的事,而仓库到底不是工作的地方。
 
②虚拟内存原本是不会导致设备系统不稳定的,在iOS3时代用过的人都应该知道,这个只是在iOS4时代之后才出现的问题。
 
③至于虚拟内存是否会影响设备的寿命,这个我想应该是可以忽略的。我通过查看一天的内存页面输出量,也就相当于写入闪存的数据量。如果不开虚拟内存大概是几MB,如果开启大概是200MB左右。如果你开启的大概是256MB,也就是平均这个区域一天才能全部写满一次。
 
当然也有的锋友担心的是对同一个区块反复擦写。其实这个是不必担心的,因为闪存有损耗平衡,它会尽量少写入擦写次数多的地方,并且每次重启虚拟内存文件都是重新创建的。除此以外只有在内存不足的时候才会写入闪存,而最主要的读取是不会影响寿命的。而nand闪存写入次数大概是10万次,结合总容量,看看有多大影响?
 
我们使用虚拟内存的主要目的是给当前运行的程序提供更多的物理内存,防止出现系统由于内存不足采取的措施导致的卡顿和闪退,当然也可以在后台运行更多的程序。
 
使用虚拟内存一定程度上可能会导致切换程序的卡顿。此时系统正在将磁盘内的数据转移到内存。
 
UNIX的虚拟内存是这样的,在内存并没有短缺的时候,就开始将内存内一些不活动的页面写入磁盘,这样当进程需要内存时候,可以直接将这部分分配给进程,如果这些不活动页面没有被分配,而占用他们的进程又需要修改储存在其中的数据,则也可以直接修改,因此唯一可能造成卡顿的操作就是激活有页面被交换到磁盘上去的进程,而即便这样,也只需要将磁盘上一部分数据读取到内存就可以。经过测试,touch4闪存读取速度是接近40MB/s,也就是说,假设一个进程占用了40M内存并被全部交换到闪存里,最多这个进程也就被暂停1s。而事实上,很少有程序会占用到40M内存,基本上就是游戏,并且一般很少会全部交换到闪存,就算这样,激活这个进程也没必要把全部页面都交换到内存里,除此以外,还记得切换程序的过渡动画吗,貌似也有1s吧。因此,几乎感觉不到卡顿的,就算有一点,也没关系啊,总比后台被关掉和前台闪退好吧。
 
因此,虚拟内存还是有很大好处的,并不是只是让内存看上去大一点的东西。
 
下面,我就来为大家剖析一下deb虚拟内存原理是什么。
其实所有的虚拟内存的deb的原理完全一样,因此横向比较其稳定性没有任何意义。简而言之,其功能只是开启了系统原生就有的功能而已。
 
所有的虚拟内存deb解包后都有一个放在/system/library/launchdeamons/里面的一个plist文件。这个路径存放的是所有开机启动的进程配置文件。一般这个plist指向启动的程序就是在/sbin/里面的dynamic_pager。也有的是指向vm,而这个vm就是deb安装后放在sbin里面的一个程序,本质上和dynamic_pager是一样的。而其他文件不过就是一些辅助用途,比如fm用来释放内存,还有一个关闭虚拟内存加密用的。
 
下面我们来讲一讲这个dynamic_pager到底是个什么东西。
其实它并不是虚拟内存的进程,虚拟内存不需要进程,是操作系统的功能。这个进程的功能是和系统通信,负责创建,删除虚拟内存文件。如果你强行干掉这个进程,虚拟内存仍然可用,但不能增加减少交换文件数量。一旦交换文件写满,当前的程序会卡死。
 
在terminal里面登陆root后直接输入dynamic_pager回车就可以开启虚拟内存。这个进程有这么几个选项:
-F 单个虚拟内存交换文件大小,默认为64m,使用时候在后面输入文件字节数。
-S 虚拟内存交换文件路径和名称,默认在/var/vm,默认文件名swapfile编号。
-H 设置当swapfile的总剩余空间低于多少字节时候创建新的交换文件。
-L 设置swapfile总剩余空间多于多少字节时删除空闲的交换文件
-P 优先级,不过貌似没什么用。
 
讲清楚了这个程序的作用,下面说说它的来历。
 
很多人以为这个是系统自带的,其实不是的。这是越狱后cydia自动安装上去的。大家打开cydia,在刚越狱完后就安装的软件包里面可以找到,有一个点开后在文件系统一项可一看到这个程序。
 
总之,这个dynamic_pager是十分重要的,尽管不是原生的,但是由其作用是开启系统的虚拟内存,我们可以知道,iOS原生就支持虚拟内存,只不过是被苹果拿掉了而已。
 
说完了这个,我再给大家讲一下虚拟内存交换文件的管理方法。
经过我的实验和查询一些资
补充:移动开发 , 其他 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,