Android Dalvik虛擬機內存分配問題

Android Dalvik虛擬機內存分配問題

                   原文地址:http://blog.csdn.net/goodlixueyong/article/details/40716779       作者:viclee108

       之前遇到一個Android上圖片加載不出來的問題,在三星的note3上極容易出現,而在nexus 4上則很難出現。後來通過DDMS觀察發現,是某一個模塊一直內存泄漏使得內存接近上限,導致一些大圖(需要的內存比較大)申請內存失敗,一直加載不出來。爲什麼會出現這種狀況呢?

      通過getprop拿到兩個手機上dalvik虛擬機的參數,三星的note3上的dalvik.vm.heapgrowthlimit爲64M,而nexus4上的dalvik.vm.heapgrowthlimit爲192M,後者是前者的三倍。也就是說note3上存在內存泄漏的時候,虛擬機的內存很容易就達到64M的上限,而在nexus4上要達到192M還是很難的,這也就解釋了前面的現象。

      說到這裏,我們來看看虛擬機的幾個重要參數的意義。

      dalvik.vm.heapstartsize  
查看方法:getprop|grep dalvik.vm.heapstartsize 

     堆分配的初始大小,調整這個值會影響到應用的流暢性和整體ram消耗。這個值越小,系統ram消耗越慢,但是由於初始值較小,一些較大的應用需要擴張這個堆,從而引發gc和堆調整的策略,會應用反應更慢。相反,這個值越大系統ram消耗越快,但是程序更流暢。

     dalvik.vm.heapgrowthlimit       
查看方法:getprop|grep dalvik.vm.heapgrowthlimit

     極限堆大小,dvm heap是可增長的,但是正常情況下dvm heap的大小是不會超過dalvik.vm.heapgrowthlimit的值。如果受控的應用dvm heap size超過該值,則將引發oom。

    dalvik.vm.heapsize 
查看方法:getprop|grep dalvik.vm.heapsize

    使用大堆時,極限堆大小。一旦dalvik heap size超過這個值,直接引發oom。android開發中,如果要使用大堆,需要在manifest中指定android:largeHeap爲true。這樣dvm heap最大可達dalvik.vm.heapsize。

    [dalvik.vm.heaptargetutilization]: [0.75]   可以設定內存利用率的百分比,當實際的利用率偏離這個百分比的時候,虛擬機會在GC的時候調整堆內存大小,讓實際佔用率向個百分比靠攏。


   上面的幾個參數是與虛擬機的內存分配相關的,虛擬機的內存分配過程是下面這樣的:

1  首先判斷一下需要申請的size是不是過大,如果申請的size超過了堆的最大限制,則轉入步驟6

2  嘗試分配,如果成功則返回,失敗則轉入步驟3

3  判斷是否gc正在進行垃圾回收,如果正在進行則等待回收完成之後,嘗試分配。如果成功則返回,失敗則轉入步驟4

4  自己啓動gc進行垃圾回收,這裏gcForMalloc的參數是false。所以不會回收軟引用,回收完成後嘗試分配,如果成功則返回,失敗則轉入步驟5

5  調用dvmHeapSourceAllocAndGrow嘗試分配,這個函數會擴張堆。所以heap startup的時候可以給一個比較小的初始堆,實在不夠用再調用它進行擴張

6  進入回收軟引用階段,這裏gcForMalloc的參數是ture,所以需要回收軟引用。然後調用dvmHeapSourceAllocAndGrow嘗試分配,如果失敗則拋出OOM。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章