Android 之 內存管理

概述html

android的開發中,要時刻主要內存的分配和垃圾回收,由於系統爲每個dalvik虛擬機分配的內存是有限的,在googleG1中,分配的最大堆大小隻有16M,後來的機器通常都爲24M,實在是少的可憐。這樣就須要咱們在開發過程當中要時刻注意。不要由於本身的代碼問題而形成OOM錯誤。java

JAVA的內存管理android

你們都知道,android應用層是由java開發的,androiddavlik虛擬機與jvm也相似,只不過它是基於寄存器的。所以要了解android的內存管理就必須得了解java的內存分配和垃圾回收機制。算法

java中,是經過new關鍵字來爲對象分配內存的,而內存的釋放是由垃圾收集器(GC)來回收的,工程師在開發的過程當中,不須要顯式的去管理內存。可是這樣有可能在不知不覺中就會浪費了不少內存,最終致使java虛擬機花費不少時間去進行垃圾回收,更嚴重的是形成JVMOOM。所以,java工程師仍是有必要了解JAVA的內存分配和垃圾回收機制。
eclipse

  1. 內存結構jvm

上面這張圖是JVM的結構圖,它主要四個部分組成:Class Loader子系統和執行引擎,運行時方法區和本地方法區,咱們主要來看下RUNTIME DATA AREA區,也就是咱們常說的JVM內存。從圖中能夠看出,RUNTIMEDATA AREA區主要由5個部分組成:工具

  • Method Area:被裝載的class的元信息存儲在Method Area中,它是線程共享的google

  • Heap():一個java虛擬機實例中只存在一個堆空間,存放一些對象信息,它是線程共享的spa

  • Java棧: java虛擬機直接對java棧進行兩種操做,以幀爲單位的壓棧和出棧(非線程共享).net

  • 程序計數器(非線程共享)

  • 本地方法棧(非線程共享)

  1. JVM的垃圾回收(GC

JVM的垃圾原理是這樣的,它把對象分爲年輕代(Young)、年老代(Tenured)、持久代(Perm),對不一樣生命週期的對象使用不一樣的垃圾回收算法。

  • 年輕代(Young)

年輕代分爲三個區,一個eden區,兩個Survivor區。程序中生成的大部分新的對象都在Eden區中,當Eden區滿時,還存活的對象將被複制到其中一個Survivor區,當此Survivor區的對象佔用空間滿了時,此區存活的對象又被複制到另一個Survivor區,當這個Survivor區也滿了的時候,從第一個Survivor區複製過來的而且此時還存活的對象,將被複制到年老代。

  • 年老代(Tenured

年老代存放的是上面年輕代複製過來的對象,也就是在年輕代中還存活的對象,而且區滿了複製過來的。通常來講,年老代中的對象生命週期都比較長。

  • 持久代(Perm

用於存放靜態的類和方法,持久代對垃圾回收沒有顯著的影響。

Android內存泄露監測

在瞭解了JVM的內存管理後,咱們再回過頭來看看,在android中應該怎樣來監測內存,從而看在應用中是否存在內存分配和垃圾回收問題而形成內存泄露狀況。

android中,有一個相對來講還不錯的工具,能夠用來監測內存是否存在泄露狀況:DDMSHeap

使用方法比較簡單:

  • 選擇DDMS視圖,並打開Devices視圖和Heap視圖

  • 點擊選擇要監控的進程,好比:上圖中我選擇的是system_process

  • 選中Devices視圖界面上的"update heap" 圖標

  • 點擊Heap視圖中的"Cause GC" 按鈕(至關於向虛擬機發送了一次GC請求的操做)

Heap視圖中選擇想要監控的Type,通常咱們會觀察dataobject total size的變化,正常狀況下total size的值會穩定在一個有限的範圍內,也就說程序中的代碼良好,沒有形成程序中的對象不被回收的狀況。若是代碼中存在沒有釋放對象引用的狀況,那麼data objecttotal size在每次GC以後都不會有明顯的回落,隨着操做次數的增長而total size也在不斷的增長。(說明:選擇好data object後,不斷的操做應用,這樣才能夠看出total size的變化)。若是totalsize確實是在不斷增長而沒有回落,說明程序中有沒有被釋放的資源引用。那麼咱們應該怎麼來定位呢?

Android中內存泄露定位

Mat(memory analyzer tools)是咱們經常使用的用來定位內存泄露的工具,若是你使用ADT,而且安裝了MATeclipse插件,你須要作的是進入DDMS視圖的Devices視圖:

點擊"dump HPROF file"按鈕,而後使用MAT分析下載下來的文件。

 

下面列出了存在的問題,點擊detail進去,會列出詳細的,可能會存在問題的代碼:

 

關於MAT的使用能夠參考:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html

這位兄弟寫的比較詳細。

總結

無論是java仍是android,都應該瞭解內存分配和垃圾回收機制,工程師要作到寫的代碼中沒有bad code很難,關鍵是在出現問題的時候該怎麼去排查。

相關文章
相關標籤/搜索