在 Android 上寫 Singletons Class 的時候,總會有些小問題困擾我。
到底 Static final Object 什麼時候會被載入?又會不會被系統給 GC 掉呢?
底下是一個常見的 Singletons pattern 寫法
到底 SingletonClass 會不會被釋放掉呢?假設目前都沒有任何的 Object reference 到 SingetonClass,為什麼它不會被釋放掉?
在 Android 這個平台上,其實很容易一個不小心就被一些奇奇怪怪的記憶體問題給玩死,因些在這時間點上,又更容易產生這個好奇。
因些,就上了 Google 大神的神壇,好好的問了一卦,最後讓我找到一個相當不錯的教學文。
Java Tip 52: Singletons vs. class (un)loading
裡面對 class loader 載入 class 及釋放的時間有了一些簡單的論述,相當的有用,其中有幾個有趣的重點:
End.
Reference:
Java Tip 52: Singletons vs. class (un)loading
到底 Static final Object 什麼時候會被載入?又會不會被系統給 GC 掉呢?
底下是一個常見的 Singletons pattern 寫法
public class SingletonClass { private static final SingletonClass mInstance = new SingletonClass(); public static SingletonClass getInstance() { return mInstance; } }這幾乎已經是從小寫到大的標準寫法(從不知道這叫 Singleton pattern 寫到知道這叫 Singleton pattern ...),但有時還是會不自覺的好奇了一下。
到底 SingletonClass 會不會被釋放掉呢?假設目前都沒有任何的 Object reference 到 SingetonClass,為什麼它不會被釋放掉?
在 Android 這個平台上,其實很容易一個不小心就被一些奇奇怪怪的記憶體問題給玩死,因些在這時間點上,又更容易產生這個好奇。
因些,就上了 Google 大神的神壇,好好的問了一卦,最後讓我找到一個相當不錯的教學文。
Java Tip 52: Singletons vs. class (un)loading
裡面對 class loader 載入 class 及釋放的時間有了一些簡單的論述,相當的有用,其中有幾個有趣的重點:
- 在 Java 1.0 之前,這個 SingletonClass 的寫法完全可以動,因為.. class unloading 根本沒實做..哈哈哈,太酷
- 但很機巴的在 Java 1.1.x 的時候,System class loader 裡面的 unloading 被弄出來了,而且,完全照著規距來。
也就是說,假設沒有任何的 GC root reference 到 SingletonClass 的 instance 了話,SingletonClass 有機會被系統給幹掉。 - 上頭說的 Java 1.1.x 很明顯的是被公幹了,因此,在 Java 1.2 的時候,規則又改啦~~而且這次的改法友善許多。
- 只要是被 system class loader 給 load 上來的 classes,class loader 就不會沒事跑去把你 unload 掉,所以你的 SingletonClass 不會沒事就被系統拿去種。
- 被其它 class loader load 上來的 classes,只有在該 class loader 被 unloaded 掉時,才會被 unload。這也某種程度上的保護了 Java 設計師不用擔心太多記憶體問題
但好玩的事情就是常常發生在這個時候....
啊我常用的 Singleton class,都需要我帶入 Context 呀!!!!
怎麼辨???
一般 Android App 在沒有任何 Component 被系統給叫醒時,是沒有 Context 可用的,那我該怎麼生成我那該死的 Singleton class??
我相信解決的方式是很多,以下是我個人最近在用的寫法,就也提供給大家參考吧。
public class SingletonClass { private static final SingletonClass mInstance = new SingletonClass(); private Context mContext; public static SingletonClass getInstance() { // if (mInstance == null) throw new RuntimeException("Are you kidding me??"); return mInstance; } /* Package Private */ static void setup(Context c) { mInstance = new SingletonClass(c) } private static SingletonClass(Context c) { mContext = c; } }
// 然後在 Application 物件中做 initialize public class SingletonDemoApp extends Application { @Override public void onCreate() { super.onCreate(); SingletonClass.setup(this); } }
End.
Reference:
Java Tip 52: Singletons vs. class (un)loading
沒有留言:
張貼留言