程序員詳解iOS的原生和第三方虛擬內存機制

發(fā)布時(shí)間:2012-1-28 11:55    發(fā)布者:1770309616
關(guān)鍵詞: iOS , 程序員 , 機制 , 虛擬內存 , 原生
虛擬內存。這項技術(shù)本質(zhì)上就是對內存地址進(jìn)行映射,使得進(jìn)程認為自己擁有連續的,大量的內存,提高內存利用率,降低程序編寫(xiě)難度。因此,虛擬內存范疇可以劃分為兩類(lèi):第一類(lèi):將進(jìn)程占用的內存地址映射到RAM內其他位置,第二類(lèi):將進(jìn)程占用的內存地址映射到磁盤(pán)上面。iOS5必定是有第一類(lèi)虛擬內存的,但沒(méi)有第二類(lèi)。

首先介紹一下虛擬內存。這項技術(shù)本質(zhì)上就是對內存地址進(jìn)行映射,使得進(jìn)程認為自己擁有連續的,大量的內存,提高內存利用率,降低程序編寫(xiě)難度。比如一個(gè)程序被系統告知其可用的內存片段是0到100頁(yè)。而實(shí)際上其占用的內存片段可能是分散的,有可能其占用的真正物理范圍是70-120頁(yè),201頁(yè)到240頁(yè),還有10頁(yè)在磁盤(pán)上面。

因此,虛擬內存范疇可以劃分為兩類(lèi):
第一類(lèi):將進(jìn)程占用的內存地址映射到RAM內其他位置。
第二類(lèi):將進(jìn)程占用的內存地址映射到磁盤(pán)上面。
而我們通俗講的虛擬內存就是第二類(lèi)。

第一類(lèi)由于都是在RAM內進(jìn)行的,速度很快,并且有專(zhuān)門(mén)硬件負責轉換,因而就像是把賓館房間的門(mén)牌號換一下而已,對程序的執行沒(méi)有任何影響。

第二類(lèi)由于磁盤(pán)的速度讀寫(xiě)速度太慢,且很多都會(huì )有一定讀寫(xiě)次數的限制,因此,當在磁盤(pán)上的頁(yè)面要被使用時(shí)候,并非直接在磁盤(pán)上修改,而是重新搬運回RAM并暫時(shí)凍結進(jìn)程,搬運完成后在RAM內被修改。而RAM內不活動(dòng)的頁(yè)面也會(huì )在內存不足時(shí)候搬運到磁盤(pán)上,為活動(dòng)的進(jìn)程提供可用的物理內存。也就是說(shuō),磁盤(pán)相當于一個(gè)倉庫而已,真正干活的地方還是在RAM里面。
這種方式使得在一些小內存的機器上也可以運行一些占用內存大程序,但是不足之處就是慢,卡。

iOS5必定是有第一類(lèi)虛擬內存的,但是沒(méi)有第二類(lèi)。

首先,如果使用虛擬內存,必定會(huì )造成一定的慢,卡,大家在PC上內存滿(mǎn)時(shí)候應該體會(huì )過(guò)。而這一點(diǎn)正是蘋(píng)果所不愿意的。蘋(píng)果一定要讓一項技術(shù)可以流暢的在設備上運行時(shí)候才讓它出現。這個(gè)很好理解,多任務(wù)就是這樣的。

其次,設備會(huì )在內存不足時(shí)候自動(dòng)關(guān)掉一些后臺程序,如果使用了這項技術(shù),就不會(huì )出現內存不足的情況,一旦內存不足,系統會(huì )自動(dòng)將一些不活動(dòng)進(jìn)程在內存里數據搬到磁盤(pán)里,為活動(dòng)的程序提供空間,因而也就是說(shuō)所有的程序都會(huì )在后臺保留,最終虛擬內存占用的磁盤(pán)空間也會(huì )越來(lái)越大。而事實(shí)上并沒(méi)有這種情況。而蘋(píng)果本身的設計也就是允許用戶(hù)不去關(guān)閉這些后臺程序。
當然,你也可以認為iOS的虛擬內存不會(huì )提供給應用程序使用。但是如果真的這樣,這虛擬內存又有什么用呢?

除此之外,蘋(píng)果也在發(fā)布會(huì )后的一次WWDC大會(huì )上說(shuō)了:limited memory/virtual memory/no swapfile。也就是說(shuō)并沒(méi)有通俗意義上的虛擬內存。

至于一些開(kāi)發(fā)者發(fā)現在terminal里面輸入top時(shí)候有一個(gè)VM的數值,并懷疑它是虛擬內存大小。那個(gè)具體是什么我也不知道,但是我認為并不是的。那個(gè)數值確實(shí)會(huì )隨著(zhù)程序開(kāi)的越多而越大,甚至可以到達4G。

下面是我分析的辦法。我將用戶(hù)盤(pán)和系統盤(pán)全部塞滿(mǎn),發(fā)現系統仍然可以正常運行。當我打開(kāi)那些程序的時(shí)候,VM的數值同樣增大,最終同樣可以到4G以上。那這部分空間是在什么地方呢?假如你說(shuō)是在除系統盤(pán)和用戶(hù)盤(pán)以外的地方,好的,這不是不可能,但我們可以算一下。我是32G的,用戶(hù)盤(pán)大小29754M,系統盤(pán)大小1024M,加起來(lái)30778M也就是30G,那剩下的4G往什么地方塞?況且一般來(lái)講由于換算原因和其它因素實(shí)際可用空間都會(huì )小于稱(chēng)標空間的。

至于iOS系統的內存管理究竟是怎么樣的呢?據我推測是這樣的。

①當內存不足時(shí)候,首先會(huì )先叫后臺程序或者系統進(jìn)程釋放。此時(shí)后臺程序會(huì )主動(dòng)釋放一些不太重要的數據資料,比如說(shuō)圖片信息之類(lèi)的,保留最重要的狀態(tài)信息,與此同時(shí)也可能對內存數據進(jìn)行壓縮。此時(shí),由于占用處理器資源,可能會(huì )出現卡頓。

②當內存依然不足時(shí),系統便開(kāi)始考慮關(guān)閉一些后臺程序了。此時(shí),后臺程序會(huì )得到信號,然后開(kāi)始運行,進(jìn)行數據的保存,完成后退出,釋放內存。此時(shí),由于會(huì )占用處理器以及儲存器,可能會(huì )再次導致卡頓。

③如果問(wèn)題還不能得到解決,系統就會(huì )強制結束前臺程序,同時(shí)在/var/logs/AppleSupport/下面留下一堆lowmemory的錯誤報告。這就是常說(shuō)的閃退的一種原因。

由此也可以說(shuō)明,iOS系統的內存管理確實(shí)很先進(jìn),確實(shí)是沒(méi)有必要去關(guān)閉后臺程序。當然,如果你認為①②步驟導致的小卡讓你很不爽,那你還是主動(dòng)去關(guān)吧。

說(shuō)完了iOS系統的內存管理,下面來(lái)說(shuō)一下用deb安裝的虛擬內存,也就是真正意義上的虛擬內存。

有人說(shuō)開(kāi)啟這種虛擬內存完全沒(méi)有用,只能是使得內存看上去增大了很多而實(shí)際上沒(méi)有任何用,還會(huì )導致系統不穩。

而我想在此澄清的是:

①虛擬內存并不能增大你設備的內存,只是為正在運行的程序騰出空間。

打個(gè)比方,就是虛擬內存并不能增大你工作間的面積,但是它給你提供了一個(gè)倉庫,可以將一些當前沒(méi)有用的東西搬進(jìn)去放著(zhù),這樣你就可以擁有更多空間干你正在干的事,而倉庫到底不是工作的地方。

②虛擬內存原本是不會(huì )導致設備系統不穩定的,在iOS3時(shí)代用過(guò)的人都應該知道,這個(gè)只是在iOS4時(shí)代之后才出現的問(wèn)題。

③至于虛擬內存是否會(huì )影響設備的壽命,這個(gè)我想應該是可以忽略的。我通過(guò)查看一天的內存頁(yè)面輸出量,也就相當于寫(xiě)入閃存的數據量。如果不開(kāi)虛擬內存大概是幾MB,如果開(kāi)啟大概是200MB左右。如果你開(kāi)啟的大概是256MB,也就是平均這個(gè)區域一天才能全部寫(xiě)滿(mǎn)一次。

當然也有的鋒友擔心的是對同一個(gè)區塊反復擦寫(xiě)。其實(shí)這個(gè)是不必擔心的,因為閃存有損耗平衡,它會(huì )盡量少寫(xiě)入擦寫(xiě)次數多的地方,并且每次重啟虛擬內存文件都是重新創(chuàng )建的。除此以外只有在內存不足的時(shí)候才會(huì )寫(xiě)入閃存,而最主要的讀取是不會(huì )影響壽命的。而nand閃存寫(xiě)入次數大概是10萬(wàn)次,結合總容量,看看有多大影響?

我們使用虛擬內存的主要目的是給當前運行的程序提供更多的物理內存,防止出現系統由于內存不足采取的措施導致的卡頓和閃退,當然也可以在后臺運行更多的程序。

使用虛擬內存一定程度上可能會(huì )導致切換程序的卡頓。此時(shí)系統正在將磁盤(pán)內的數據轉移到內存。

UNIX的虛擬內存是這樣的,在內存并沒(méi)有短缺的時(shí)候,就開(kāi)始將內存內一些不活動(dòng)的頁(yè)面寫(xiě)入磁盤(pán),這樣當進(jìn)程需要內存時(shí)候,可以直接將這部分分配給進(jìn)程,如果這些不活動(dòng)頁(yè)面沒(méi)有被分配,而占用他們的進(jìn)程又需要修改儲存在其中的數據,則也可以直接修改,因此唯一可能造成卡頓的操作就是激活有頁(yè)面被交換到磁盤(pán)上去的進(jìn)程,而即便這樣,也只需要將磁盤(pán)上一部分數據讀取到內存就可以。經(jīng)過(guò)測試,touch4閃存讀取速度是接近40MB/s,也就是說(shuō),假設一個(gè)進(jìn)程占用了40M內存并被全部交換到閃存里,最多這個(gè)進(jìn)程也就被暫停1s。而事實(shí)上,很少有程序會(huì )占用到40M內存,基本上就是游戲,并且一般很少會(huì )全部交換到閃存,就算這樣,激活這個(gè)進(jìn)程也沒(méi)必要把全部頁(yè)面都交換到內存里,除此以外,還記得切換程序的過(guò)渡動(dòng)畫(huà)嗎,貌似也有1s吧。因此,幾乎感覺(jué)不到卡頓的,就算有一點(diǎn),也沒(méi)關(guān)系啊,總比后臺被關(guān)掉和前臺閃退好吧。

因此,虛擬內存還是有很大好處的,并不是只是讓內存看上去大一點(diǎn)的東西。

下面,我就來(lái)為大家剖析一下deb虛擬內存原理是什么。
其實(shí)所有的虛擬內存的deb的原理完全一樣,因此橫向比較其穩定性沒(méi)有任何意義。簡(jiǎn)而言之,其功能只是開(kāi)啟了系統原生就有的功能而已。

所有的虛擬內存deb解包后都有一個(gè)放在/system/library/launchdeamons/里面的一個(gè)plist文件。這個(gè)路徑存放的是所有開(kāi)機啟動(dòng)的進(jìn)程配置文件。一般這個(gè)plist指向啟動(dòng)的程序就是在/sbin/里面的dynamic_pager。也有的是指向vm,而這個(gè)vm就是deb安裝后放在sbin里面的一個(gè)程序,本質(zhì)上和dynamic_pager是一樣的。而其他文件不過(guò)就是一些輔助用途,比如fm用來(lái)釋放內存,還有一個(gè)關(guān)閉虛擬內存加密用的。

下面我們來(lái)講一講這個(gè)dynamic_pager到底是個(gè)什么東西。
其實(shí)它并不是虛擬內存的進(jìn)程,虛擬內存不需要進(jìn)程,是操作系統的功能。這個(gè)進(jìn)程的功能是和系統通信,負責創(chuàng )建,刪除虛擬內存文件。如果你強行干掉這個(gè)進(jìn)程,虛擬內存仍然可用,但不能增加減少交換文件數量。一旦交換文件寫(xiě)滿(mǎn),當前的程序會(huì )卡死。

在terminal里面登陸root后直接輸入dynamic_pager回車(chē)就可以開(kāi)啟虛擬內存。這個(gè)進(jìn)程有這么幾個(gè)選項:
-F 單個(gè)虛擬內存交換文件大小,默認為64m,使用時(shí)候在后面輸入文件字節數。
-S 虛擬內存交換文件路徑和名稱(chēng),默認在/var/vm,默認文件名swapfile編號。
-H 設置當swapfile的總剩余空間低于多少字節時(shí)候創(chuàng )建新的交換文件。
-L 設置swapfile總剩余空間多于多少字節時(shí)刪除空閑的交換文件
-P 優(yōu)先級,不過(guò)貌似沒(méi)什么用。

講清楚了這個(gè)程序的作用,下面說(shuō)說(shuō)它的來(lái)歷。

很多人以為這個(gè)是系統自帶的,其實(shí)不是的。這是越獄后cydia自動(dòng)安裝上去的。大家打開(kāi)cydia,在剛越獄完后就安裝的軟件包里面可以找到,有一個(gè)點(diǎn)開(kāi)后在文件系統一項可一看到這個(gè)程序。

總之,這個(gè)dynamic_pager是十分重要的,盡管不是原生的,但是由其作用是開(kāi)啟系統的虛擬內存,我們可以知道,iOS原生就支持虛擬內存,只不過(guò)是被蘋(píng)果拿掉了而已。

說(shuō)完了這個(gè),我再給大家講一下虛擬內存交換文件的管理方法。
經(jīng)過(guò)我的實(shí)驗和查詢(xún)一些資料,我總結出來(lái)了其管理的特點(diǎn)。
其映射方式很有可能直接由內存地址映射到閃存的物理地址,也就是說(shuō)其讀寫(xiě)不用經(jīng)過(guò)文件管理系統,直接按照閃存的物理地址寫(xiě)入。因此你將虛擬內存文件刪除不會(huì )影響虛擬內存的工作。而其生成這個(gè)文件的唯一目的是占個(gè)位置,讓操作系統和別的程序知道這個(gè)區域是有用途的,防止其他程序在這塊地址創(chuàng )建文件導致內存數據被篡改。
除此以外,無(wú)論你怎么設權限,就算全部權限取消,就是每個(gè)用戶(hù)組讀取,寫(xiě)入,執行都取消,也不影響虛擬內存,交換文件一樣被修改。很有可能其完全不受文件管理系統控制,完全獨立開(kāi)來(lái)。因此修改其權限沒(méi)有什么意義。很多人說(shuō)修改為777,事實(shí)上000還更穩定。

最后,也就是大家最關(guān)心的,為什么虛擬內存不穩定,原理見(jiàn)下。

虛擬內存造成系統不穩定的直接原因就是重要進(jìn)程崩潰和出錯。
崩潰還算一種比較好的結果。
如果是普通程序,就是閃退,safari最典型。
如果是springboard,就是安全模式。
如果是launch,就是重啟。

進(jìn)程出錯可能會(huì )導致當機,而最為嚴重的是對某些文件的錯誤修改,也就是虛擬內存導致白蘋(píng)果的重要原因,當然我還遇到過(guò)所有程序消失之類(lèi)的現象。

因為每次進(jìn)程崩潰都會(huì )在/var/logs/AppleSupport下面留下錯誤報告。經(jīng)過(guò)長(cháng)時(shí)間的搜集和整理,發(fā)現其主要都是一類(lèi)錯誤,就是SIGABRT或者SIGBUS。這都是常見(jiàn)的內存錯誤,一般都是由于進(jìn)程請求了一個(gè)錯誤的內存地址導致的,錯誤報告附帶了這個(gè)地址。我還發(fā)現,其請求的地址都是超出了RAM范圍的。也就是說(shuō)其請求的是被交換到閃存上的部分。

一個(gè)開(kāi)啟了虛擬內存的機器,當出現這種情況時(shí),系統會(huì )檢測出進(jìn)程請求的地址溢出,此時(shí)會(huì )出現中斷,也就是處理器停止處理當前正在處理的任務(wù),轉而處理一個(gè)臨時(shí)新增的任務(wù),也就是將這個(gè)地址映射到的磁盤(pán)區域的數據轉移到內存里面,然后再恢復之前的任務(wù)。也就是說(shuō),出現這種情況時(shí)候很可能此時(shí)系統并沒(méi)有中斷,當前正在執行的任務(wù)沒(méi)有停止,沒(méi)有進(jìn)行數據的轉移,最終導致內存地址出錯。這個(gè)同樣可以解釋進(jìn)程出錯,可能數據轉移還沒(méi)有完成,原先的任務(wù)卻開(kāi)始運行,此時(shí)溢出的內存地址已經(jīng)映射到內存區,不會(huì )出現內存錯誤,但是數據轉移沒(méi)有完成,也就是說(shuō)這塊區域的數據并不是全是閃存里的數據,結果就是進(jìn)程出錯。

造成這個(gè)的因素是這樣的。

蘋(píng)果為了流暢,反應靈敏可謂無(wú)所不用極其。大家也知道ios的用戶(hù)界面渲染優(yōu)先級非常高,完全有可能蘋(píng)果直接把用戶(hù)界面渲染也作為了一個(gè)中斷。中斷也是有優(yōu)先級的。如果這個(gè)中斷優(yōu)先級高于虛擬內存的,就可能出現上面講的情況,數據還沒(méi)有轉移完,虛擬內存的任務(wù)卻被停止了,而處理器開(kāi)始處理用戶(hù)界面渲染的任務(wù)。如果剛好用戶(hù)界面渲染的數據被交換到了閃存上,而沒(méi)來(lái)得及轉移到RAM內,就會(huì )出現內存地址溢出或者進(jìn)程出錯,最典型就是安全模式和花屏。而Springboard和用戶(hù)界面渲染關(guān)系最為密切,這樣也可以解釋為什么這個(gè)進(jìn)程崩潰的次數最多。

要想解決這個(gè)問(wèn)題,就要降低用戶(hù)界面渲染優(yōu)先級或者取消其中斷的權利,當然也可以提高虛擬內存中斷的優(yōu)先級。這一步仍然有待研究來(lái)實(shí)現。
本文地址:http://selenalain.com/thread-85470-1-1.html     【打印本頁(yè)】

本站部分文章為轉載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀(guān)點(diǎn)和對其真實(shí)性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問(wèn)題,我們將根據著(zhù)作權人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页