內存調試的東西D/dalvikvm( 809 ): GC_CONCURRENT freed

通常Java虛擬機要求支持verbosegc選項,輸出詳細的垃圾收集調試信息。dalvik虛擬機很安靜的接受verbosegc選項,而後什麼都不作。dalvik虛擬機使用本身的一套LOG機制來輸出調試信息。 
若是在Linux下運行adb logcat命令,能夠看到以下的輸出: 
D/dalvikvm(  745): GC_CONCURRENT 
freed 199K, 53% free 3023K/6343K,external 0K/0K, paused 2ms+2ms 
 
其中D/dalvikvm表示由dalvikvm輸出的調試信息,括號後的數字表明dalvikvm所在進程的pid。 
GC_CONCURRENT表示觸發垃圾收集的緣由,有如下幾種:
GC_MALLOC, 內存分配失敗時觸發
GC_CONCURRENT,當分配的對象大小超過384K時觸發
GC_EXPLICIT,對垃圾收集的顯式調用(System.gc)
GC_EXTERNAL_ALLOC,外部內存分配失敗時觸發
freed 199K表示本次垃圾收集釋放了199K的內存, 
53% free 3023K/6343K,其中6343K表示當前內存總量,3023K表示可用內存,53%表示可用內存佔總內存的比例。 
external 0K/0K,表示可用外部內存/外部內存總量 
paused 2ms+2ms,第一個時間值表示markrootset的時間,第二個時間值表示第二次mark的時間。若是觸發緣由不是GC_CONCURRENT,這一行爲單個時間值,表示垃圾收集的耗時時間。 
 
2. 分析 
(1)雖然dalvikvm提供了一些調試信息,可是還缺少一些關鍵信息,好比說mark和sweep的時間, 分配內存失敗時是由於分配多大的內存失敗,還有對於SoftReference,WeakReference和PhantomReference的處理,每次垃圾收集處理了多少個這些引用等。 
(2)目前dalvik全部線程共享一個內存堆,這樣在分配內存時必須在線程之間互斥,能夠考慮爲每一個內存分配一個線程局部存儲堆,一些小的內存分配能夠直接從該堆中分配而無須互斥鎖。 
(3)dalvik虛擬機中引入了concurrentmark,可是對於多核CPU,能夠實現parrelmark,便可以使用多個線程同時運行mark階段。這些都是目前dalvik虛擬機內存管理能夠作出的改進。

GC_FOR_MALLOC means that the GC was triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created.html

GC_EXPLICIT means that the garbage collector has been explicitly asked to collect, instead of being triggered by high water marks in the heap. Happens all over the place, but most likely when a thread is being killed or when a binder communication is taken down.java

There are a few others as well:app

GC_CONCURRENT Triggered when the heap has reached a certain amount of objects to collect.線程

GC_EXTERNAL_ALLOC means that the the VM is trying to reduce the amount of memory used for collectable objects, to make room for more non-collectable.調試

typedefenum{ 
    GC_FOR_MALLOC, 
    GC_CONCURRENT, 
    GC_EXPLICIT, 
    GC_EXTERNAL_ALLOC, 
    GC_HPROF_DUMP_HEAP 
   }GcReason; orm

GC_EXTERNAL_ALLOC freed 297K, 49% free 3411K/6663K, external 24870K/26260K, paused 83mshtm

      前面Free的內存是VM中java使用的內存,external是指VM中經過JNI中Native的類中的malloc分配出的內存,例如Bitmap和一些Cursor都是這麼分配的。
在Davilk中,給一個程序分配的內存根據機型廠商的不一樣,而不一樣,如今的大部分的是32M了,而在VM內部會把這些內存分紅java使用的內存和 Native使用的內存,它們之間是不能共享的,就是說當你的Native內存用完了,如今Java又有空閒的內存,這時Native會從新像VM申請,而不是直接使用java的。
例如上邊的例子
free 3411K/6663K和external 24870K/26260K
若是這時須要建立一個2M的Bitmap,Native現有內存26260-24870=1390K<2048k,所以他就會向Vm申請內存,雖然java空閒的內存是
6663-3411=3252>2048,但這部份內存Native是不能使用。
可是你如今去申請2M的Native內存,VM會告訴你沒法分配的,由於如今已使用的內存已經接近峯值了32M(26260+6663=32923 ),因此如今就會成force close 報OOM。因此如今咱們要檢查咱們的native內存的使用狀況來避免OOM。對象

 

文章轉載自:http://blog.sina.com.cn/s/blog_6610da390101bhqj.htmlblog

相關文章
相關標籤/搜索