Android GC 學習筆記

hjm_1fb1990發表於2017-07-20

閱讀的文章:Android GC 原理探究

下面補充一些備註和筆記。

演算法

複製演算法 (Copying)圖示:

這裡寫圖片描述

標記-壓縮演算法 (Mark-Compact)英文描述:
mark-compact
總結起來就是 標記 —> 壓縮有用的物件到一端 —> 回收此端外剩下的空間
圖示:

這裡寫圖片描述

可以看出,這兩種演算法都可以減少記憶體碎片

GC Roots

英文官方說明:


The root kinds are:

  • Class - class loaded by system class loader. Such classes can never be unloaded. They can hold objects via static fields. Please note that classes loaded by custom class loaders are not roots, unless corresponding instances of java.lang.Class happen to be roots of other kind(s).
  • Thread - live thread
  • Stack Local - local variable or parameter of Java method
  • JNI Local - local variable or parameter of JNI method
  • JNI Global - global JNI reference
  • Monitor Used - objects used as a monitor for synchronization
  • Held by JVM - objects held from garbage collection by JVM for its purposes. Actually the list of such objects depends on JVM implementation. Possible known cases are: the system class loader, a few important exception classes which the JVM knows about, a few pre-allocated objects for exception handling, and custom class loaders when they are in the process of loading classes. Unfortunately, JVM provides absolutely no additional detail for such objects. Thus it is up to the analyst to decide to which case a certain “Held by JVM” belongs.

If an object is a root, it is specially marked in all views showing individual objects.
中文

為什麼GC會引起應用暫停(STW Stop The World)

因為gc需要確保標記準確無誤,所以不可能一邊標記,一邊還有建立和銷燬物件的活動,只能是暫定所有執行緒,等標記和清理完成後恢復所有執行緒。

弱引用(soft reference)

Android效能提升之強引用、軟引用、弱引用、虛引用使用

可以應用到安卓開發中的tips

  • 我們首先要儘量避免掉頻繁生成很多臨時小變數(比如說:getView,onDraw等函式),以減少gc頻率和記憶體碎片。
    另外,又要儘量去避免產生很多長生命週期的大物件,減少老年代執行gc的次數。 Old GC的速度一般會比Young gc慢10倍以上。並且執行”標記-壓縮演算法”,標記和壓縮階段都會暫停應用,造成較長時間的STW。

  • 也可以註冊一個應用不可見(比如鎖屏,被放到後臺)的生命週期回撥,主動觸發gc, 因為反正應用不可見,GC 下以便之後執行更流暢,不過只是設想,還沒實驗。

  • 作者也說了,本來想故意“生成一些幾百K的物件,試圖去擴大可用堆大小的時候,反而會導致頻繁的GC,因為這些物件的分配會導致GC,而GC後會讓堆記憶體回到合適的比例,而我們使用的區域性變數很快會被回收理論上存活物件還是那麼多,我們的堆大小也會縮減回來無法達到擴充的目的”此路不通。

相關文章