本篇文章主要介紹 Android 開發中的部分知識點,經過閱讀本篇文章,您將收穫如下內容:
1、App內存優化概述
2、監視可用內存和內存使用狀況
3、合理的釋放內存
4、分析App須要用多少內存
5、使用內存優化框架
6、移除內存密集型資源,以及lib庫
更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS
免費獲取面試PDF合集android
隨機存取存儲器(RAM
)在任何軟件開發環境中都是很是有價值的資源,但對於物理內存常常受到限制的移動操做系統來講,它更有價值。儘管Android運行時(ART)
和Dalvik虛擬機
都執行常規垃圾收集,但這並不意味着您能夠忽略應用程序分配和釋放內存的時間和位置。您仍然須要避免引入內存泄漏,這些一般由靜態成員變量中的對象引用引發,並在生命週期回調定義的適當時間釋聽任何引用對象。git
本頁面介紹瞭如何主動減小應用程序中的內存使用量。有關Android操做系統如何管理內存的信息,請參閱Android內存管理概述github
在修復解決APP
中的內存使用問題以前,首先須要找到它們。 Android Studio
中的內存分析器Memory Profiler
能夠幫助您經過如下方式查找和診斷內存問題:面試
Memory Profiler
顯示了一個實時圖,顯示您的應用程序使用了多少內存,分配了Java對象的數量以及什麼時候發生垃圾回收。編程
啓動垃圾收集事件並在運行應用程序時抓取Java堆的快照。數組
而後檢查全部分配的對象,查看每一個分配的堆棧跟蹤,而後跳轉到Android Studio
編輯器中的相應代碼。緩存
Android能夠經過多種方式從您的應用程序中回收內存,或者在必要時將應用程序完全關閉以釋放內存以用於關鍵任務。爲了進一步幫助平衡系統內存,避免系統須要終止應用程序進程,能夠在Activity
類中實現ComponentCallbacks2
接口提供的onTrimMemory()
回調方法,從而容許您的應用程序在處於前臺或後臺時偵聽與內存相關的事件,而後釋放對象以響應應用程序生命週期,或者指示系統須要回收內存的系統事件。數據結構
例如,您能夠實現onTrimMemory()
回調以響應不一樣的內存相關事件,以下所示app
import android.content.ComponentCallbacks2; // Other import statements ... public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { // Other activity code ... /** * Release memory when the UI becomes hidden or when system resources become low. * @param level the memory-related event that was raised. */ public void onTrimMemory(int level) { // Determine which lifecycle or system event was raised. switch (level) { case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN: /* Release any UI objects that currently hold memory. The user interface has moved to the background. */ break; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE: case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW: case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: /* Release any memory that your app doesn't need to run. The device is running low on memory while the app is running. The event raised indicates the severity of the memory-related event. If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will begin killing background processes. */ break; case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND: case ComponentCallbacks2.TRIM_MEMORY_MODERATE: case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: /* Release as much memory as the process can. The app is on the LRU list and the system is running low on memory. The event raised indicates where the app sits within the LRU list. If the event is TRIM_MEMORY_COMPLETE, the process will be one of the first to be terminated. */ break; default: /* Release any non-critical data structures. The app received an unrecognized memory level value from the system. Treat this as a generic low-memory message. */ break; } } }
onTrimMemory()
回調方法是在Android 4.0時候添加的,以前版本請用onLowMemory()
方法,跟TRIM_MEMORY_COMPLETE
事件處理同樣。框架
爲了容許多個正在運行的進程,Android
爲每一個應用程序分配的堆大小設置了硬限制。確切的堆大小限制根據設備有多少整體可用RAM
不一樣而有所不一樣。若是您的應用程序已達到堆容量並嘗試分配更多內存,則系統將引起OutOfMemoryError
。
爲了不OutOfMemoryError
內存不足,能夠查詢系統以肯定當前設備上有多少可用的堆空間。你能夠經過調用getMemoryInfo()
來查詢這個數字。這將返回一個ActivityManager.MemoryInfo
對象,該對象提供有關設備當前內存狀態的信息,包括可用內存,總內存以及內存閾值(即系統開始中斷進程的內存級別)。 ActivityManager.MemoryInfo
對象還暴露了一個簡單的布爾值,lowMemory
,能夠判斷你設備是否在低內存下運行。
以下例子,舉例使用getMemoryInfo()
public void doSomethingMemoryIntensive() { // Before doing something that requires a lot of memory, // check to see whether the device is in a low memory state. ActivityManager.MemoryInfo memoryInfo = getAvailableMemory(); if (!memoryInfo.lowMemory) { // Do memory intensive work ... } } // Get a MemoryInfo object for the device's current memory status. private ActivityManager.MemoryInfo getAvailableMemory() { ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); return memoryInfo; }
一些Android
功能,Java類和代碼構造傾向於使用比其餘更多的內存。您能夠經過在代碼中選擇更有效的替代方法來最大限度地減小應用程序使用的內存量
在不須要Services的狀況下運行Services,是形成最嚴重的內存管理錯誤之一。
若是你的應用程序須要一個Services來在後臺執行工做,那麼除非它須要運行一個後臺任務,不然不要讓它保持運行。記得在完成任務時中止Services。不然,您可能會無心中形成內存泄漏。
當你啓動一個Services時, 系統須要始終保持運行該Services的進程。此行爲使得Services進程很是昂貴,由於Services使用的RAM對其餘進程仍然不可用。這樣能夠減小系統在LRU
緩存中保留的緩存進程的數量,從而下降應用程序切換的效率。內存不足時系統甚至可能致使系統崩潰,系統沒法維護足夠的進程來承載當前運行的全部服務。
您一般應該避免使用持久性Persistent Services
,由於這些服務會常駐系統內存。相反,咱們建議您使用諸如JobScheduler
之類的替代實現。有關如何使用JobScheduler
安排後臺進程的更多信息,請參閱後臺優化。
若是您必須使用服務,那麼限制服務使用壽命的最好方法就是使用IntentService
,一旦完成了處理啓動它的意圖,IntentService
就會自動完成。有關更多信息,請閱讀在後臺服務中運行。
編程語言提供的某些類未針對在移動設備上使用進行優化。例如,通用的HashMap
實現多是至關低效的內存,由於每一個映射都須要單獨的入口對象。
Android
框架包括幾個優化的數據容器,包括SparseArray,SparseBooleanArray和LongSparseArray
。例如,SparseArray
類更有效率,由於它們避免了系統須要自動複製密鑰的狀況,有時還須要建立另一個或兩個對象。
若有必要,您能夠隨時切換到原始數組以得到精簡的數據結構。
協議緩衝區是一種語言中立,平臺無關,可擴展的機制,由Google設計,用於序列化結構化數據 - 相似於XML
,但更小,更快,更簡單。若是你決定爲你的數據使用protobufs
,你應該老是在你的客戶端代碼中使用nano protobufs
。常常protobufs
生成很是詳細的代碼,這可能會致使您的應用程序中的許多種問題,如增長的RAM使用,APK
大小增長,和較慢的執行。
有關更多信息,請參閱protobuf自述文件中的「Nano版本」部分。
如前所述,垃圾收集事件一般不會影響您的應用程序的性能。可是,不少短期內發生的垃圾收集事件可能會很快消耗掉你的幀時間。系統花費在垃圾收集上的時間越多,執行其餘內容(如渲染或流式傳輸音頻)的時間就越少。
內存流失一般會致使大量的垃圾收集事件發生。在實踐中,內存流失描述了在給定的時間內發生的分配的臨時對象的數量。
例如,您能夠在for
循環中分配多個臨時對象。或者您能夠在視圖的onDraw()
函數內建立新的Paint
或Bitmap
對象。在這兩種狀況下,應用程序都會以大批量快速建立大量對象。這些可能會迅速消耗年輕一代中的全部可用內存,從而迫使垃圾收集事件發生。
固然,你須要在你的代碼中找到內存流失高的地方,而後才能修復它們。爲此,您應該在Android Studio
中使用Memory Profiler
。
你的代碼中的一些資源和庫能夠在你不知道的狀況下吞噬內存。您的APK
的總體大小(包括第三方庫或嵌入式資源)可能會影響您的應用消耗的內存量。您能夠經過從代碼中刪除冗餘,沒必要要或臃腫的組件,資源或庫來改善應用程序的內存消耗。
您能夠經過減小應用程序的總體大小來顯着減小應用程序的內存使用量。好比:bitmap大小,res資源,動畫幀數以及第三方庫均可以影響APK
的大小。 Android Studio
和Android SDK
提供了多種工具來幫助您減小資源和外部依賴的大小。
有關如何減小您的總體APK
大小的更多信息,請參閱縮小APK
大小。
依賴注入框架能夠簡化您編寫的代碼,並提供適用於測試和其餘配置更改的自適應環境。
若是您打算在應用程序中使用依賴項注入框架,請考慮使用Dagger 2
. Dagger 2不使用反射來掃描您的應用程序的代碼。Dagger的靜態編譯實現,意味着它能夠在Android
應用程序中使用,而無需增長運行成本或內存使用。
其餘使用反射的依賴注入框架傾向於經過掃描代碼來註釋來初始化進程。這個過程可能須要更多的CPU週期和內存,而且在應用程序啓動時會引發明顯的滯後
外部庫代碼一般不是針對移動環境編寫的,並且在用於移動客戶端時可能效率低下。當您決定使用外部庫時,您可能須要爲移動設備優化該庫。預先計劃好這個工做,而後根據代碼大小和內存佔用狀況來分析這個庫,而後才決定使用它。
即便一些移動優化的庫可能因爲不一樣的實現而致使問題。例如,一個庫可能使用nano protobufs
,而另外一個庫使用微型protobufs
,致使您的應用程序中有兩個不一樣的protobuf
實現。這可能發生在不一樣的日誌記錄,分析,圖像加載框架,緩存以及許多您不但願的事情上。
儘管ProGuard
能夠幫助您使用正確的標誌刪除API和資源,但它不能刪除庫的大型內部依賴關係。您須要在這些庫中的功能可能須要較低級別的依賴關係。若是庫使用反射,這是常見的,而且意味着您須要花費大量時間手動調整ProGuard
才能使用反射,那麼當您從庫中使用Activity子類時,這每每會產生大量的依賴關係工做等等。。
更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS
免費獲取面試PDF合集