在以前的文章中咱們總結過跟Android 內存相關的知識或者問題,這裏先列舉一下:html
1. Java 內存回收機制——GC機制數據庫
2. Java 對象引用方式 —— 強引用、軟引用、弱引用和虛引用性能優化
3. Android Studio 使用Memory Monitor進行內存泄露分析性能
4. Android OOM 引起的思考優化
5. Android 常見 Memory Leak 緣由及解決辦法總結 ui
從以前整理的內存來看,咱們首先須要瞭解的就是Java內存使用及回收相關的知識,而後在Android上涉及內存管理問題主要就是內存抖動、內存泄漏、內存溢出。spa
本文咱們針對性能優化再次作一下Android開發時咱們能對內存方面進行優化的內容,雖然有點贅述,可是但願能溫故知新。code
首先咱們先了解一下Android的內存分配策略,而後再談一下如何優化內存問題。htm
進程的內存分配策略爲:由 ActivityManagerService
集中管理全部進程的內存分配。對象
進程的內存回收策略爲:
首先 Application Framework 決定回收的類型,當進程的內存空間緊張時會按照進程優先級由低到高的順序自動回收進程及內存。
Android Framework將進程分爲5個優先級,具體以下:
真正執行回收進程的操做的是 Linux 內核。
梳理一下總體流程:
1. ActivityManagerService 對全部進程進行評分。
2. 更新評分到 Linux 內核。
3. 由 Linux 內核完成真正的內存回收。
Android 對對象、變量的內存策略和Java是同樣的,對內存的管理即爲 對象&變量的內存分配和內存釋放。下面咱們講一下內存分配和內存釋放的策略:
對象&變量的內存分配有系統負責,共有三種:靜態分配、棧式分配、堆式分配,分別面向靜態變量,動態變量和對象實例。
對象&變量的內存釋放由Java的垃圾回收器GC負責。
常見的內存問題以下:
1. 內存抖動
2. 內存泄漏
3. 內存溢出
常見引起內存泄漏的主要狀況有:
核心點:被static修飾過的成員變量的生命週期 = 應用程序的生命週期。
泄漏緣由:若被static修飾的成員變量引用短生命週期的實例,則容易出現該成員變量的生命週期 > 引用實例生命週期的狀況,當引用實例需結束生命週期銷燬時,會因靜態變量的持有而沒法被回收,從而出現內存泄露。
解決方案:
a. 儘可能避免static成員變量引用資源消耗過多的實例(若需引用Context,則儘可能使用Application的Context)。
b. 使用弱引用WeakReference代替強引用持有實例。
核心點:單例模式 其生命週期的長度 = 應用程序的生命週期
泄漏緣由:若1個對象已不需再使用 而單例對象還持有該對象的引用,那麼該對象將不能被正常回收 從而 致使內存泄漏
解決方案:單例模式引用的對象的生命週期 = 應用的生命週期。 或者編寫代碼保證在合適的時機釋放資源。
核心點:非靜態內部類默認持有外部類的引用,可能會致使外部類對象沒法釋放,形成內存泄漏。
解決方案:使用靜態內部類。
泄露緣由:對於資源的使用(如 廣播BraodcastReceiver
、文件流File
、數據庫遊標Cursor
、),若在Activity
銷燬時沒有及時關閉或註銷這些資源,則這些資源將不會被回收,從而形成內存泄漏。
Activity
銷燬時 及時關閉 / 註銷資源
核心緣由:頻繁建立大量、臨時的小對象。
優化方案:避免建立大量、臨時的小對象。
請參考:Android OOM 引起的思考。這裏就不過多整理了。