和你一起終身學習,這裡是程式設計師Android
經典好文推薦,通過閱讀本文,您將收穫以下知識點:
一、Android 垃圾回收機制(GC)
二、共享內存
三、內存的申請與回收
四、內存限制
五、不同App切換時的內存管理
Android Runtime(ART)和Dalvik虛擬機使用 分頁 和 內存映射 來管理內存。這意味著應用程式修改的任何內存(無論是通過分配新對象通過映射頁面)都將保留在RAM中,並且不能被分頁。
應用程式釋放內存的唯一方法是釋放應用程式持有的對象引用,即使垃圾收集器回收(GC)回收內存 。
比如:如果系統想要在其他地方使用該內存,則可以將任何未經修改的映射到mmap中文件(例如代碼)分頁出RAM。
本頁面介紹了Android如何管理應用程式進程和內存分配。有關如何在應用程式中更高效地管理內存的更多信息,請參閱管理您的應用程式的內存。
一、Android 垃圾回收機制(GC)ART 或 Dalvik虛擬機的託管內存環境會跟蹤每個內存分配情況。一旦它確定一段內存不再被程序使用,它將它釋放回堆(Heap)中,並且不需要程式設計師的任何幹預。回收託管內存環境中未使用內存的機制稱為垃圾回收(GC)。
1.垃圾回收機制的目的垃圾回收機制的目的:
1.在程序中查找將來不再使用的數據對象(Object)
2.回收這些對象所佔用的內存資源。
Android 內存是一個典型的堆內存(Heap),這意味著系統會根據被分配的對象的預期壽命和大小有不同的分配桶。
例如,最近分配的對象屬於年輕一代。當一個對象保持足夠的活動時間時,它可以被提升到一個老一代,然後是一個永久的時代。
每個堆的生成都有自己佔用內存的上限。任何時候一旦內存即將被填滿,系統就會執行一個垃圾回收事件去試圖釋放內存。垃圾收集的持續時間取決於它正在回收的那個對象以及回收多少個正在活躍的對象。
儘管垃圾器回收的速度相當快,但它仍然可能會影響應用程式的性能。並且你一般不會控制垃圾器回收你代碼事件的時間。
系統垃圾回收機制具有一定運行中的標準,這個標準主要用於確定何時執行垃圾收集。當條件滿足時,系統停止執行進程並開始垃圾收集。
如果垃圾回收發生在密集的處理循環(如動畫)或音樂播放期間,可能會增加處理時間。這種增長可能會推動您的應用程式執行代碼超過推薦的16ms閾值,以實現高效流暢的幀渲染。
此外,您的代碼流可能會執行各種強制垃圾收集事件的工作,或使其持續時間超過正常。例如,如果在alpha混合動畫的每個幀期間在for循環的最內部分配了多個對象,則可能會佔用大量的內存堆,並使用大量對象。在這種情況下,垃圾收集器將執行多個垃圾收集事件,並可能降低應用程式的性能。
有關垃圾收集的更多一般信息,請參閱垃圾收集。
二、共享內存為了適應不同的RAM需求,Android 嘗試在不同進程之間共享內存,共享內存的方法如下:
1. APP共享Framework框架代碼以及資源每個APP的進程都是從Zygote進程中分離出來的。
Zygote 進程:
Zygote進程是在系統啟動並加載Framwork框架代碼和資源(如Activity Theme)時開始。要啟動一個新的應用程式進程,系統會從Zygote進程fork分離出來,然後在新進程中加載並運行應用程式的代碼。這種方法允許大部分分配給Framework框架代碼和資源的RAM頁面與所有應用程式進程之間共享。
大多數靜態數據被映射到一個進程。這種技術允許數據在進程之間共享,並允許在需要時將其分頁。示例靜態數據包括:Dalvik代碼(通過將其放置在用於直接映射的預連結.odex文件中),應用程式資源(通過將資源表設計為可以被映射的結構以及通過對齊APK的zip條目) 以及.so文件中的本地代碼等傳統項目元素。
3. Android使用顯式分配的共享內存區域(使用ashmem或gralloc)共享同一個動態RAM。例如,窗口表面使用應用程式和屏幕合成器之間的共享內存,遊標緩衝區使用內容提供者和客戶端之間的共享內存。
由於共享內存的廣泛使用,確定您的應用使用多少內存需要謹慎。在調查您的RAM使用情況中討論了正確確定應用程式內存使用情況的技巧。如需獲取更多內容,請看RAM使用情況分析詳解。
三、APP內存的申請與回收Dalvik 虛擬機會限制每個應用程式進程的虛擬內存範圍。它定義了邏輯堆的大小,並且可以根據需要增長,但只能達到系統為每個應用程式定義的限制。
堆的邏輯大小與堆使用的物理內存量不同。在檢查應用程式的堆時,Android 會計算一個名為「比例集合大小** Proportion Set Size 」(PSS)** 的值,該值與其他進程共享的髒頁面(Page)和乾淨頁面(Page),並且數量與多少應用程式共享該RAM成正比。(PSS)總數是系統認為是您的物理內存的足跡。有關PSS的更多信息,請參閱RAM使用情況指南。
Dalvik堆不壓縮堆的邏輯大小,這意味著 Android不會整理堆以關閉空間。當堆的末尾有未使用的空間時,Android只能縮小邏輯堆的大小。然而,系統仍然可以減少堆使用的物理內存。在垃圾收集之後,Dalvik遍歷堆並找到未使用的頁面,然後使用madvise將這些頁面返回給內核。
因此,成對的大塊分配和釋放應該會導致所有(或幾乎全部)所使用的物理內存的回收。但是,從小分配中回收內存的效率可能會低得多,因為用於小分配的頁面仍可能與尚未釋放的其他內容共享。
為了維護一個主要的多功能環境,Android 對每個應用程式的堆大小設定了一個硬限制。確切的堆大小限制根據設備有多少RAM可用而有所不同。如果您的應用程式已達到堆容量並嘗試分配更多內存,則可能會收到OutOfMemoryError。
在某些情況下,您可能需要查詢系統以確定在當前設備上有多少堆空間可用 。
例如,確定有多少數據可以安全地保留在緩存中。你可以通過調用getMemoryClass()來查詢這個數字。此方法返回一個整數,指示可用於應用程式堆的兆字節數。
當用戶在應用程式之間進行切換時,Android會保留不在前臺的應用程式(即對用戶不可見,或者在最近最少使用(LRU)緩存中運行諸如音樂播放之類的前臺服務)。例如,當用戶第一次啟動應用程式時,會為其創建一個進程; 但是當用戶離開應用程式時,該過程不會退出。系統保持進程緩存。如果用戶稍後返回到應用程式,系統將重新使用該進程,從而使應用程式切換更快。
如果您的應用程式具有緩存的進程,並且保留了當前不需要的內存,那麼您的應用程式(即使用戶不使用它)也會影響系統的整體性能。由於系統內存不足,它會以最近使用最少的進程開始,終止LRU緩存中的進程。系統也考慮到保存最多內存的進程,並可以終止它們以釋放RAM。
注意:當系統開始在LRU緩存中查殺進程時,它主要是自下而上的。系統也考慮哪些進程消耗更多的內存,從而為系統提供更多的內存增益。在整個LRU列表中消耗的內存越少,留在列表中的機會就越好,並能夠快速恢復。
友情推薦:
Android 開發乾貨集錦
至此,本篇已結束。轉載網絡的文章,小編覺得很優秀,歡迎點擊閱讀原文,支持原創作者,如有侵權,懇請聯繫小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!
點個在看,方便您使用時快速查找!