吐血整理!究極深刻Android內存優化(一)

前言:

成爲一名優秀的Android開發,須要一份完備的知識體系,在這裏,讓咱們一塊兒成長爲本身所想的那樣~。php

本篇是 Android 內存優化的進階篇,難度能夠說達到了煉獄級別,建議對內存優化不是很是熟悉的仔細看看前篇文章:Android性能優化以內存優化,其中詳細分析瞭如下幾大模塊:java

1)、Android的內存管理機制算法

2)、優化內存的意義json

3)、避免內存泄漏數組

4)、優化內存空間緩存

5)、圖片管理模塊的設計與實現性能優化

若是你對以上基礎內容都比較瞭解了,那麼咱們便開始 Android 內存優化的探索之旅吧。工具

直接進入正題,沖沖衝!!!post

1、重識內存優化

Android給每一個應用進程分配的內存都是很是有限的,那麼,爲何不能把圖片下載下來都放到磁盤中呢?那是由於放在內存中,展現會更 「快」,快的緣由有兩點,以下所示:性能

1)、硬件快:內存自己讀取、存入速度快。

2)、複用快:解碼成果有效保存,複用時,直接使用解碼後對象,而不是再作一次圖像解碼。

這裏說一下解碼的概念。Android系統要在屏幕上展現圖片的時候只認 「像素緩衝」,而這也是大多數操做系統的特徵。而咱們常見的jpg,png等圖片格式,都是把 「像素緩衝」 使用不一樣的手段壓縮後的結果,因此這些格式的圖片,要在設備上展現,就必須通過一次解碼,它的執行速度會受圖片壓縮比、尺寸等因素影響。(官方建議:把從內存中淘汰的圖片,下降壓縮比後存儲到本地,以備後用,這樣能夠最大限度地下降之後複用時的解碼開銷。)

下面,咱們來了解一下內存優化的一些重要概念。

一、手機RAM

手機不使用PC的DDR內存,採用的是LPDDR RAM,即 」低功耗雙倍數據速率內存「。其計算規則以下所示:

LPDDR系列的帶寬 = 時鐘頻率 ✖️內存總線位數 / 8LPDDR4 = 1600MHZ ✖️64 / 8 ✖️雙倍速率 = 25.6GB/s。複製代碼

那麼內存佔用是否越少越好?

當系統內存充足的時候,咱們能夠多用一些得到更好的性能。當系統內存不足的時候,咱們但願能夠作到 」用時分配,及時釋放「。

二、內存優化的緯度

對於Android內存優化來講又能夠細分爲以下兩個維度,以下所示:

1)、RAM優化

2)、ROM優化

一、RAM優化

主要是下降運行時內存。它的目的有以下三個:

1)、防止應用發生OOM。

2)、下降應用因爲內存過大被LMK機制殺死的機率。

3)、避免不合理使用內存致使GC次數增多,從而致使應用發生卡頓。

二、ROM優化

下降應用佔ROM的體積,進行APK瘦身。它的目的主要是爲了下降應用佔用空間,避免因ROM空間不足致使程序沒法安裝。

三、內存問題

那麼,內存問題主要是有哪幾類呢?內存問題一般來講,能夠細分爲以下三類:

1)、內存抖動

2)、內存泄漏

3)、內存溢出

下面,咱們來了解下它們。

一、內存抖動

內存波動圖形呈鋸齒張、GC致使卡頓。

這個問題在Dalvik虛擬機上會更加明顯,而ART虛擬機在內存管理跟回收策略上都作了大量優化,內存分配和GC效率相比提高了5~10倍,因此出現內存抖動的機率會小不少。

二、內存泄漏

Android系統虛擬機的垃圾回收是經過虛擬機GC機制來實現的。GC會選擇一些還存活的對象做爲內存遍歷的根節點GC Roots,經過對GC Roots的可達性來判斷是否須要回收。內存泄漏就是在當前應用週期內再也不使用的對象被GC Roots引用,致使不能回收,使實際可以使用內存變小。簡言之,就是對象被持有致使沒法釋放或不能按照對象正常的生命週期進行釋放。通常來講,可用內存減小、頻繁GC,容易致使內存泄漏。

三、內存溢出

即OOM,OOM時會致使程序異常。Android設備出廠之後,java虛擬機對單個應用的最大內存分配就肯定下來了,超出這個值就會OOM。單個應用可用的最大內存對應於 /system/build.prop 文件中的 dalvik.vm.heapgrowthlimit。

此外,除了因內存泄漏累積到必定程度致使OOM的狀況之外,也有一次性申請不少內存,好比說一次建立大的數組或者是載入大的文件如圖片的時候會致使OOM。並且,實際狀況下不少OOM就是因圖片處理不當而產生的。

2、常見工具選擇

一、Memory Profiler

做用

1)、實時圖表展現應用內存使用量。

2)、用於識別內存泄漏、抖動等。

3)、提供捕獲堆轉儲、強制GC以及根據內存分配的能力。

優勢

1)、方便直觀

2)、線下使用

二、Memory Analyzer

強大的Java Heap分析工具,查找內存泄漏及內存佔用,生成總體報告、分析內存問題等等。建議線下深刻使用。

三、LeakCanary

自動化內存泄漏檢測神器。建議僅用於線下集成。

它的缺點比較明顯,具體有以下兩點:

1)、雖然使用了idleHandler與多進程,可是dumphprof 的 SuspendAll Thread 的特性依然會致使應用卡頓。

2)、在三星等手機,系統會緩存最後一個Activity,此時應該採用更嚴格的檢測模式。

3、Android內存管理機制回顧

ART 和 Dalvik 虛擬機使用分頁和內存映射來管理內存。下面咱們先從Java的內存分配開始提及。

一、Java 內存分配

Java的內存分配區域分爲以下五部分:

1)、方法區:主要存放靜態常量。

2)、虛擬機棧:Java變量引用。

3)、本地方法棧:native變量引用。

4)、堆:對象。

5)、程序計數器:計算當前線程的當前方法執行到多少行。

二、Java 內存回收算法

一、標記-清除算法

流程可簡述爲兩步:

1)、標記全部須要回收的對象。

2)、統一回收全部被標記的對象。

優勢

實現比較簡單。

缺點

1)、標記、清除效率不高。

2)、產生大量內存碎片。

二、複製算法

流程可簡述爲三步:

1)、將內存劃分爲大小相等的兩塊。

2)、一塊內存用完以後複製存活對象到另外一塊。

3)、清理另外一塊內存。

優勢

實現簡單,運行高效,每次僅需遍歷標記一半的內存區域。

缺點

會浪費一半的空間,代價大。

三、標記-整理算法

流程可簡述爲三步:

1)、標記過程與 標記-清除算法 同樣。

2)、存活對象往一端進行移動。

3)、清理其他內存。

優勢

1)、避免 標記-清除 致使的內存碎片。

2)、避免複製算法的空間浪費。

四、分代收集算法

如今主流的虛擬機通常用的比較多的仍是分代收集算法,它具備以下特色:

1)、結合多種算法優點。

2)、新生代對象存活率低,使用 複製算法。

3)、老年代對象存活率高,使用 標記-整理算法。

三、Android 內存管理機制

Android 中的內存是彈性分配的,分配值 與 最大值 受具體設備影響。

對於OOM場景其實能夠細分爲以下兩種:

1)、內存真正不足。

2)、可用(被分配的)內存不足。

咱們須要着重注意一下這兩種的區分。

四、小結

以Android中虛擬機的角度來講,咱們要清楚Dalvik 與 ART 區別,Dalvik僅固定一種回收算法,而ART回收算法可在運行期按需選擇,而且,ART具有內存整理能力,減小內存空洞。

最後,LMK(Low Memory killer)機制保證了進程資源的合理利用,它的實現原理主要是根據進程分類和回收收益來綜合決定的一套算法集。

原文連接https://juejin.im/post/5e780257f265da575209652c

做者:jsonchao

後續小編將持續更新,幫助到你的話記得關注轉發哦~~

相關文章
相關標籤/搜索