• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • Android Memory Management

    發表于:2013-04-07來源:futurexiong的博客作者:futurexiong點擊數: 標簽:軟件測試Android
    從早期G1的192MB RAM開始,到現在動輒1G -2G RAM的設備,為單個App分配的內存從16MB到48MB甚至更多,但OOM從不曾離我們遠去。這是因為大部分App中圖片內容占據了50%甚至75%以上,而App內容的極大豐富,所需的圖片越來越多,屏幕尺寸也越來越大分辨率也越來越

      從早期G1的192MB RAM開始,到現在動輒1G -2G RAM的設備,為單個App分配的內存從16MB到48MB甚至更多,但OOM從不曾離我們遠去。這是因為大部分App中圖片內容占據了50%甚至75%以上,而App內容的極大豐富,所需的圖片越來越多,屏幕尺寸也越來越大分辨率也越來越高,所需的圖片的大小也跟著往上漲,這在大屏手機和平板上尤其明顯。而且還經常要兼容低版本的設備。所以Android的內存管理顯得極為重要。

      在這里我們主要講兩件事情:

      1.Gingerbread和Honeycomb中的一些影響你使用內存的變化

      -heap size

      -GC

      -bitmaps

      2.理解heap的用途分配

      -logs

      -merory leaks

      -Eclispe Memory Analyzer(MAT)

      首先第一部分,我們都知道Android是個多任務操作系統,同時運行著很多程序,都需要分配內存,不可能為一個程序分配越來越多的內存以至于讓整個系統都崩潰,因此heap的大小有個硬性的限制,跟設備相關,從發展來說也是越來越大,G1:16MB,Droid:24MB,Nexus One:32MB,Xoom:48MB,但是一旦超出了這個使用的范圍,OOM便產生了。如果你正在開發一個應用,想知道設備的heap大小的限制是多少,比方說根據這個值來估算自己應用的緩存大小應該限制在什么樣一個水平,你可以使用ActivityManager.getMemoryClass ()來獲得一個單位為MB的整數值,一般來說最低不少于16MB,對于現在的設備而言這個值會越來越大,24MB,32MB,48MB甚至更大。

      但是對于一些內存非常吃緊的比如圖片瀏覽器等應用,在平板上所需的內存更大了。因此在Honeycomb之后AndroidManifest.xml增加了largeHeap的選項

    1
    2
    3
    4
    <application
           android:largeHeap="true"
           ...
    </application>
    

      這允許你的應用使用更多的heap,可以用ActivityManager.getLargeMemoryClass ()返回一個更大的可用heap size。但是這里要警告的是,千萬不要因為你的應用報OOM了而使用這個選項,因為更大的heap size意味著更多的GC時間,意味著應用的性能越來越差,而且用戶也會發現其他應用很有可能會內存不足。只有你需要使用很多的內存而且非常了解每一部分內存的用途,這些所需的內存都是不可或缺的,這個時候你才應該使用這個選項。

      剛剛我們提到更大的heap size意味著更多的GC時間,下面我們來談談Garbage Collection。

    1.jpg

      如上圖所示,GC會選擇一些它了解還存活的對象作為內存遍歷的根節點,比方說thread stack中的變量,JNI中的全局變量,zygote中的對象等,然后開始對heap進行遍歷。到最后,部分沒有直接或者間接引用到GC Roots的就是需要回收的垃圾,會被GC回收掉。如下圖藍色部分。

    2.jpg

      因此也可以看出,更大的heap size需要遍歷的對象更多,回收垃圾的時間更長,所以說使用largeHeap選項會導致更多的GC時間。

      在Gingerbread之前,GC執行的時候整個應用會暫停下來執行全面的垃圾回收,因此有時候會看到應用卡頓的時間比較長,一般來說>100ms,對用戶而言已經足以察覺出來。Gingerbread及以上的版本,GC做了很大的改進,基本上可以說是并發的執行,也不是執行完全的回收,只有在GC開始以及結束的時候會有非常短暫的停頓時間,一般來說<5ms,用戶也不會察覺到。

      在Honeycomb之前,Bitmap的內存分配如下圖。

    3.jpg

      藍色部分是Dalvik heap,黃色部分是Bitmap引用對象的堆內存,而Bitmap實際的Pixel Data是分配在Native Memory中。這樣做有幾個問題,首先需要調用reclyce()來表明Bitmap的Pixel Data占用的內存可回收,不調用這個方法的話就要靠finalizer來讓GC回收這部分內存,但了解finalizer的應該都知道這相當的不可靠;其次是很難進行Debug,因為一些內存分析工具是查看不到Native Memory的;再次就是不調用reclyce()需要回收Native Memory中的內存的話會導致一次完整的GC,GC執行的時候會暫停整個應用。

      Honeycomb之后,Bitmap的內存分配做出了改變,如下圖

    4.jpg

      藍色黃色部分沒有變化,但Bitmap實際的Pixel Data的內存也同樣分配在了Dalvik heap中。這樣做有幾個好處。首先能同步的被GC回收掉;其次Debug變得容易了,因為內存分析工具能夠查看到這部分的內存;再次就是GC變成并發了,可做部分的回收,也就是極大縮短了GC執行時暫停的時間。

      接下來我們講第二部分。一般來說我們希望了解我們應用內存分配,最基本的就是查看Log信息。比方說看這樣一個Log信息(這是Gingerbread版本的,Honeycomb以后log信息有改動):

      D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/

      9991K, external 4703K/5261K, paused 2ms 2ms

      GC_XXX表明是哪類GC以及觸發GC的原因。幾種GC類型:

      - GC_CONCURRENT:這是因為你的heap內存占用開始往上漲了,為了避免heap內存滿了而觸發執行的。

      - GC_FOR_MALLOC:這是由于concurrent gc沒有及時執行完而你的應用又需要分配更多的內存,內存要滿了,這個時候不得不停下來進行malloc gc。

    原文轉自:http://my.eoe.cn/futurexiong/archive/1299.html

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>