當前位置:首頁 » 賬號管理 » 一個進程啟動時的內存管理是怎樣的
擴展閱讀
新手機最好怎樣設置 2024-11-21 02:29:48
熟牛肉怎樣做好吃 2024-11-21 02:14:37
電腦中大小寫怎樣切換 2024-11-21 02:05:35

一個進程啟動時的內存管理是怎樣的

發布時間: 2022-12-11 23:52:54

A. Android 內存管理機制是怎麼樣的呢

「安卓內存管理機制」理論上看起來很好,可實際呢?

自從看了「安卓內存管理機制」,我也不殺進程了,說是快速啟動,最後是不管啟動什麼程序,卡得跟老太太走路似,真受不了。還有那個說什麼內存用滿了會自動殺一些沒用的進程,沒錯,會殺進程,不過不是殺沒用的,而是殺有用的。

就是有時候想一邊聽歌一邊上網,當時只要一個酷狗和一個uc開著就行了,可是老是自動把我的酷狗給關了,然後動手開了,過不了一會兒又自動給關了,一個手機不可能兩個程序都開不了,就是這個內存管理機制還不夠智能,老保留著沒用的,殺有用的,真是氣死人了。有時候用那些手機衛士去殺進程,過不了多久那些進程又有了。直接重啟!和蘋果對比,說真的,蘋果手機我不是很喜歡,第一,太貴,第二,在下載軟體、刷機方面不夠自由。綜合這兩條,也就是自己動手可玩性不高。

但是不得不承認,在運行方面蘋果真的很流暢,就算用了幾年,和新買時運行的速度差別都不大。安卓的用個一年就卡掉牙了。

B. 內存要怎樣管理與維護

管理一、 進程的虛擬地址空間

每個進程都被賦予自己的虛擬地址空間,對於32位進程來說,這個地址空間為4G,因此進程中的地址可以為0X00000000至0XFFFFFFFF之間的任何一個值。其中4G空間中的低區的2G空間留給進程使用,而高區的2G空間則留給系統使用。

在Windows2000下,分區情況為:

1、 NULL指針分配的分區

NULL指針分配的分區占據0x00000000至0x0000FFFF,該分區的設置是為了幫助程序員掌握NULL指針的分配情況。例如當malloc或new分配失敗時就返回NULL,該分區的地址是禁止進入的,訪問該分區內的地址將發生訪問違規現象,同時終止該進程的運行。

2、 用戶方式分區

該分區是進程私有的地址空間,對於應用程序來講,該分區是維護進程的大部分數據的地方,所有的.exe和dll模塊均載入在這個分區,每個進程可以將dll載入到不同的地址中。對於.exe而言,一般載入到0x00400000地址處。

進程的棧和堆也是在該分區中開辟的。

3、 禁止進入分區

該分區是用戶方式分區上禁止進入的分區,位於0x7FFF0000至0x7FFFFFFF,訪問該分區的任何企圖均將導致訪問違規,該分區的存在是為了防止用戶從用戶區訪問內核區的代碼。如:

BYTE buf[70000];

DWORD numWritten;

WriteProcessMemory(GetCurrentProces(), (PVOID)0x7FFEEE90, buf, sizeof(buf), &numWritten);

將有可能成功地將數據寫入只能有內核方式代碼訪問的內存。

4、 內核方式分區

該分區是存放操作系統代碼的地方,用於線程調度、內存管理、文件系統支持、網路支持和所有設備驅動程序的代碼全部在這個分區載入駐留在該分區的一切均可被所有近進程共享。

二、 虛擬內存的實現

本質上虛擬內存就是要讓一個程序的代碼和數據再沒有全部載入內存的情況下運行程序。運行過程中,當執行到尚未載入的內存代碼,或者要訪問還沒有載入到內存的數據時,虛擬內存管理器動態的將這部分代碼或數據從硬碟載入到內存中。而且在通常情況下,虛擬內存管理器也會相應的將內存中某些代碼或者數據置換到硬碟中,為即將載入的代碼或數據騰出地方。

Win32中用來輔助實現虛擬內存的硬碟文件稱為「調頁文件」,調頁文件用來存放被虛擬內存管理器置換處內存的數據,當這些數據再次被進程訪問時,虛擬內存管理器會先將它們從調頁文件中置換進內存,這樣進程可以正確訪問這些數據。

程序代碼(包括exe和dll文件)不會被修改,所以他們所在的頁被置換處內存時,並不會被寫進調頁文件中,而是直接拋棄,當再次被需要時,虛擬內存管理器直接從存放他們的exe或dll文件中找到他們並調入內存。

三、 虛擬內存的狀態

近處虛擬地址空間中的頁有三種狀態:自由(free)、預留(reserved)和提交(committed)。

1、自由

自由表示此頁尚未分配出去,可以用來滿足新的內存分配請求。

2、預留

預留是指從虛擬地址空間中劃出一塊區域(頁的整數倍大小),劃出之後的區域中的頁不能用來滿足新的內存分配請求,只是用來供要求「預留」此段區域的代碼以後使用,預留狀態的區域並沒有分配物理存儲,只是增加了一個描述進程虛擬地址空姐使用狀態的數據結構,用來記錄這塊區域已倍預留。

3、提交

提交內存時會從調頁文件中開辟空間,並修改VAD中的相應項。當然,此時並沒有立刻從物理內存中分配空間,只是從磁碟的調頁文件中開辟空間。

當有代碼第一次訪問這段提交內存中的某些數據時,系統發現並沒有真正的物理內存,拋出缺頁異常,虛擬內存管理器處理該異常,此時才會真正的分配物理內存。

四、 虛擬內存狀態的管理

Win32虛擬內存管理器使用一個數據結構(Virtual Address Descriptor, VAD)來記錄和維護每個進程4G的虛擬地址空姐的使用及狀態,美國進程都有自己的VAD集合,這個集合被組織成一個自平衡二叉樹。只有預留或提交的內存塊才有VAD,自由的內存塊沒有VAD,因此不在VAD數據結構中的虛擬地址就是自由的。每塊VAD數據結構記錄了該塊的起始地址以及當前狀態。

五、 訪問虛擬內存時的處理流程

對某虛擬內存區域進行了預留並提交之後,就可以對該區域中的數據進行訪問了,一下為訪問虛擬內存時的處理流程。

1、當被訪問數據已在物理內存時,虛擬內存管理器只需記那個該數據的虛擬地址映射為物理指針。

2、當被訪問的數據不在物理內存時,檢測此數據是否在調頁文件中或者在exe或dll文件中,若存在則進入下一步,否則發生訪問違例錯誤,進程退出。

3、判斷內存中是否有空閑頁,若存在空閑頁,則直接將調頁文件或exe或dll文件的數據載入到該空閑頁中。

虛擬內存管理器維護了一個稱為「頁幀資料庫page-frame database」的數據結構,該數據結構時操作系統全局的,當系統啟動時被初始化,用來跟蹤和記錄物理內存真能乾的每個頁的狀態。

4、當內存中不存在空閑頁時,根據調頁演算法,首先選擇出某個頁作為換出頁。

5、判斷此頁自上次調進後是否修改過,若沒有被修改過,則將需要訪問的數據調入此頁,若被修改過,則需要先將此頁的內容寫到調頁文件與此頁相對應的備份頁中,並隨即將此頁標記為空閑頁。

六、 虛擬地址到物理地址的映射

當訪問的數據已在物理內存中後,需要將虛擬地址轉換為物理地址,即「地址映射」,才能真正訪問此數據。

每個進程都維護一套自己的層次表結構來實現地址映射。

第一層稱為「目錄表」,實際上是一個內存頁,以四個位元組為單元分成1024個項,每一項稱為「頁目錄項」。

第二層稱為「頁表」,共有1024個頁表,頁目錄表中的每個目錄表項對應這一層中的某個頁表,每個頁表也佔一個內存也,同樣被分成1024項,表頁的每一項稱為「頁表項」,每個頁表項指向物理內存中的某一個頁幀。

第三層稱為頁幀,是真正存數數據的地方。

當進行地址映射的時候,對應於層次表中的三個部分,頁將32位的地址分成三個部分,最高的十位對應頁目錄下標,次高的十位對應頁表的下標,低位的12位對應位元組下標作為頁內定址。
維護最好別讓進程佔用內存大和長時間,沒用的進程盡快關,保持系統的順利;用優化大師優化內存,定時檢查內存有無病毒。硬體維護方面就要看看內存槽有沒有積塵灰,有的話要清理,清理時候也要注意一下別傷到內存槽和內存。

C. 內存管理機制

一內存管理機制概述

從操作系統的角度來說,內存就是一塊數據存儲區域,而且他是可以被操作系統調動的資源。在現在的多進程操作系統當中,內存管理十分重要。操作系統它會為每一個進程合理分配內存資源,這里我們來從兩個角度來分析,什麼是內存管理機制。

1、分配機制

操作系統它會為每一個進程分配一個合理的大小,從而他能保證每一個進程能夠正常的運行。而不至於內存不夠使用或者某個進程佔用太多的內存,這就是操作系統裡面的分配概念。

2、回收機制(這一塊是操作系統特別重要的一塊)

  在系統內存不足的時候,他會有一個回收再分配內存資源的機制,從而能夠保證新的進程能夠正常運行。而回收的時候就要殺死那些佔有內存的進程,所以操作系統需要提供一套合理的殺死這些進程的機制,從而把副作用將到最低,而對於我們安卓系統來說,它對內存管理也有一套特別的辦法,它和PC端是不一樣的。我們都知道安卓它是移動操作系統,一般情況下安卓的內存資源會比PC端更少,所以我們就要更加謹慎的管理內存。

二 Android 內存管理機制

1、分配機制

我們知道,安卓在為每一個進程分配內存的時候,它採用了一個彈性的分配方式,比如剛開始他不會為一個新的APP分配太多的內存空間,而是給每一個app進程分配一個小額的內存量,而這個量是根據每一個移動端設備物理尺寸大小所決定,隨著你的APP不斷的運行,你可能發現當前內存已經不夠使用了,這個時候安卓就會為每一個進程分配額外的大小,但是我們需要注意的是,分配的額外的內存大小不是隨意去分配的,他是有限度的。因為我們都知道,安卓的內存大小是有限制的,所以說系統不可能為每一個APP進程分配無限大的內存.

總結:安卓的分配機制它的最大限度就是讓更多的進程存活在內存當中,當用戶下次再次啟動時,他就不需要重新創建進程,他只需要恢復已有的進程即可,這樣就減少了應用啟動的時候,提高用戶體驗。

2、回收機制

安卓對內存的使用,他的宗旨是盡最大限度的使用。它是繼承linux的特點,安卓系統他會在內存中保存盡可能多的數據。這里也有一個缺點,比如說有的進程不再被使用,但是數據還保存在內存當中,所以現在安卓不推薦直接退出應用。如果這樣當用戶下次啟動應用的時候,只需要恢復當前進程即可,而不需要創建新進程。當安卓發現內存不夠使用,開始回收內存的時候,安卓就會殺死其他進程。來回收足夠的內存,從而開啟新的進程。這里注意,對於進程分配他有一個優先順序的概念,

優先順序它主要分為五個階段。

  第一:前台進程,屏幕當中顯示的進程

  第二:可見進程,他已經不屬於前台進程,用戶仍能看見的進程,

  第三:服務進程,例如定位、鬧鍾等。

  第四:後台進程,後台進程不同於服務進程,它是在後台處理一些計算的進程.

  第五:空進程,沒有任何東西在內存運行的進程。內存可以隨時回收。

三、安卓中為什麼會有這五個分級

答:因為優先順序越低的進程,被內存回收的概率越大

  1、例如前台進程、可見進程、服務進程:一般情況下是不會被殺死的,

  2、後台進程:他會存放在一個緩存的列表中,就是lru(最進最少使用的)緩存機制,先殺死的進程他會處於這個列表的尾部(也就是最進最少使用的後台進程會被第一個殺死)。

  3、空進程:他是為了平衡整個系統的性能,安卓是不會保存這些進程的,

四、回收效率概念是什麼

答:當安卓開始殺死進程的時候,系統會判斷每一個殺死後所帶來的回收效益,因為安卓更喜歡殺死一個能夠回收更多內存的進程,在這里我們就知道,可以殺死更多的進程,來獲取更多的內存。當然我們還是希望能夠殺死少的進程,這樣對用戶的體驗影響越小。

五、遵循內存管理機制的目標

答:我們在開發項目的時候,都會給APP頂訂一個內存目標,這目標有以下幾點:

  1、更少的佔用內存:我們都知道,如果一個APP性能更好,站用戶手機的內存越少,這樣對用戶的體驗,都是一個很好的目標。

  2、在合適的時候,合理的釋放系統資源。(並不是你不要的馬上就要回收,如果頻繁的釋放對象,會造成內存抖動,而內存抖動會造成很多不好的現象,比如UI卡頓、anr、甚至是oom)

  3、在系統內存緊張的時候,能釋放掉大部分不重要的資源,來為Android系統提供可用的內存。

  4、能夠很合理的在特殊生命周期中,保存或者還原重要數據,以至於系統能夠正確的重新回復應用

六、內存優化方法。

答:我們在開發項目的時候,都會給APP頂訂一個內存目標,這目標有以下幾點:

  1、當service完成任務,盡量停止它。我們知道service進程優先順序是比較低的,他的優先順序叫做服務進程。所以這會影響到它的內存回收,這里我們可以用IntentService替換Service完成所需要的任務。

    好處有兩點:

    第一點:我們知道IntentService是繼承Service,他也是一個服務,但是他不同Service的地方,Service是默認在主線程,所以Service不可以做耗時操作, 是內部開啟一個子線程,所以在他的onHandleIntent方法中,可以做一些耗時操作。

    第二點:IntentService執行完之後他會自動停止,而Service必須手動調用才能停止,如果Service沒有退出就會造成內存的泄露。

  2、在UI不可見的時候,釋放掉一些只有UI使用的資源

  3、在系統內存緊張的時候,盡可能多的釋放掉一些非重要的資源。

  4、避免濫用Bitmap導致資源浪費。(根據當前解析度壓縮Bitmap是最好的選擇,只用後要調用recycle方法釋放掉Bitmap在C內存中的內存,也可以使用軟引用引用一個Bitmap,然後使用lru緩存,來對Bitmap進行緩存演算法)

  5、使用針對內存優化過的數據容器,少用枚舉常量,它消耗的內存是普通常量的兩倍多

  6、避免使用依賴注入框架。:例如我們項目開發過程中,會使用很多的注入框架,例如ButterKnife。使用這些依賴框架有好的地方,但是也會給我們帶來額外的服務。

  7、使用多進程,例如定位、推送、WebView就可以寫一個後台進程來執行。特別是Webview如果不開啟一個進程的話就會造成內存泄露。