ANDROID開發之GC_CONCURRENT freed


 

<GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>

<回收原因><回收內存總數><可用內存百分比><外部內存狀態><回收占用時間>
每隔一段時間,系統回收器都會打印內存回收的情況。日志的內容格式就是上面那條格式。

老是看到LOG日志里有些系統回收的東西。明知道是內存問題。但還真不知道怎么下手。唉,無奈啊。網上找資料海里撈針,不容易啊。看到這篇不錯。

1. verbosegc
一般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_HPROF_DUMP_HEAP,創建HPROF文件分析內存堆棧時觸發
  • GC_EXTERNAL_ALLOC,外部內存分配失敗時觸發(API Level 10及以下才有)

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虛擬機內存管理可以做出的改進。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM