**本文爲翻譯官方文檔,若有錯誤,請指正**html
Android運行時(ART)和Dalvik虛擬機使用分頁和內存映射來管理內存。這意味着一個應用程序修改的任何內存,不管是經過分配新的對象或者觸摸內存映射頁面--都將駐留在RAM中,不能被分頁。釋放一個應用內存的惟一方式是釋放被程序持有的對象引用,在垃圾回收以後內存變爲可用。假如系統想在任何地方使用該內存,則任何未修改的文件內存映射均可以被移除RAM。android
這篇文章說明Android如何管理進程和內存分配。更多在應用程序中如何更加高效管理內存,請看管理應用內存程序員
一個託管內存環境,像ART或者Dalvik虛擬機,保持對每一次內存分配的跟蹤。一旦肯定一塊內存不在被程序使用,將它釋放回堆,而不須要程序員的額外操做。在託管內存環境恢復未使用的內存機制就叫垃圾回收。垃圾回收有2個目的:找到未來不會被訪問的數據對象,並回收這些對象的資源。緩存
Android堆內存是一代(gennerational one)的,意味着他們是不一樣的桶分配(buckets of allocations),跟蹤依賴於正在分配的對象生命週期和大小。例如,最近分配的對象屬於存在於年輕代,存活時間久的對象就晉升爲老年代,緊隨其後是永久的一代。安全
每個堆棧代都有其獨立的佔用對象內存上限。任什麼時候候,只要一個代佔用滿了,系統執行垃圾回收爲了空出內存。垃圾回收持續時間徹底依賴於某一代回收的對象和每一代中還有多少對象存活着。數據結構
雖然垃圾回收很是快,它依舊可能影響程序性能。經過代碼,你不能徹底控制垃圾回收什麼時候執發生。系統具備運行的一套標準,用於肯定什麼時候執行垃圾收集。當條件被知足,系統掛起進程並執行垃圾回收。若是垃圾回收發生在一個密集處理之間,像執行動畫或者播放音樂中間,它會增長進程執行時間。這種增長可能會潛在的推進代碼執行超過建議的16ms閾值,以實現高效和平滑的幀渲染。框架
此外,你的代碼可能執行各類各樣的工做,致使常常強制執行垃圾回收事件或者使得垃圾回收事件比正常持續更長時間。例如,在alpha混合動畫的每個幀期間,在for循環的最內部分配過多的對象,則可能致使過多的對象污染你的內存堆。在這種狀況下,垃圾回收器執行屢次垃圾回收事件可能致使程序性能下降。ide
更多關於垃圾回收的信息,參考垃圾回收。性能
爲了適用RAM中須要的一切,Android嘗試跨進程共享RAM分頁。它能夠在如下方式中使用。動畫
因爲大量使用內存共享,須要注意決定您的應用程序使用多少內存。正確決定應用程序使用內存的技術在調查RAM使用中被討論。
Dalvik堆爲每一個應用進程限制單一的虛擬內存範圍。這定義了應用邏輯堆大小,它能夠隨着須要擴展但只能達到系統爲每一個應用程序限定的大小。
堆的邏輯大小與堆使用的物理內存量不相同。當檢查應用程序堆時,Android訪問實際使用的內存計算一個值,該值稱爲與其它進程共享髒分頁和乾淨分頁的比例,但只能和共享RAM的應用程序成正比。實際使用內存總量是系統考慮你的物理內存佔用。更多關於PSS(Proportional Set Size)的信息,請看調查RAM使用狀況導讀。
Dalvik堆不會對堆的邏輯大小進行壓縮,這意味着Android不會整理堆內存碎片以關閉空間。Android僅僅能壓縮處於堆末尾未使用空間中的邏輯堆大小。然而,系統仍舊能回收被堆使用的物理內存。在垃圾回收以後,Dalvik操做堆並找到未使用的分頁,並經過使用madvise把這些分頁返回給內核。所以,配合分配和從新分配大塊地址,可能致使回收所有(幾乎全部)已使用的物理內存。然而,從小的分配內存中回收內存可能效率要低不少,由於被小的內存分配佔用的分頁,可能同時也被其它未釋放的其它內容共享。
爲了維持多任務的工做環境,Android爲每個應用程序設置了硬性的堆上線。準確的上線,依賴於設備所有能提供的RAM大小在不一樣設備之間有不一樣。假如你的應用程序已經快到堆容量了而且依舊嘗試分配更多內存,就會返回一個內存溢出錯誤。
在不少狀況下,你但願查系統,以肯定在當前設備上你能夠的堆大小。例如,肯定在緩存文件中保存多少數據是安全的。你能夠經過調用getMemoryClass()來查詢系統的這個數字。這個方法返回一個數字代表你的應用程序有多少兆可用字節
當用戶切換應用程序,在用戶最近使用(LRU)的緩存中,Android保持那些不在前臺的應用程序--那些對於用戶不可見或者像音樂播放器在前臺運行的服務。例如,當用戶第一次啓動一個應用的時候,系統爲它建立了一個進程,可是當用戶離開這個應用的時候,這個進程並無被退出。系統保持這個進程在緩存中。假如用戶以後回到這個應用程序,系統恢復這個進程,從而 可使得切換應用程序更快。
假如你的應用程序擁有緩存進程而且保留了那些沒有使用的內存-即便用戶沒有使用應用程序--它也會影響系統的總體性能。當系統在低內存運行的時候,系統開始殺死那些最近不多使用的在LRU緩存進程。系統還考慮那些持有大部份內存的進程並考慮終止他們以釋放RAM。
注意:當系統開始殺死LRU緩存中的進程時,首先從低向上開始工做。系統也考慮那些佔用不少內存而且殺死它系統能夠獲取更多內存的進程。在LRU列表中佔用的內存越少,在列表中保留下來的機會就越大,而且能夠更加快的恢復。
更多關於進程沒有在前臺運行若是保存在緩存中,而且Android設備如何選擇哪個進程去殺死,請看進程和線程導讀。
原文地址:https://developer.android.google.cn/topic/performance/memory-overview.html