[英]Memory allocation difference between Singleton vs static final instance
public class MyClass {
private static MyClass instance = null;
private MyActivity myActivity;
private Button button;
public static MyClass getInstance(){
if (instance == null){
instance = new MyClass();
}
return instance;
}
private MyClass(){};
public void initialize(MyActivity activity){
myActivity = activity;
}
public void releaseMemory(){
instance = null;
}
}
在這種方法中,只要我的應用程序退出,我就可以通過調用releaseMemory()釋放內存,從而不會泄漏myActivity實例。
public class MyClass {
private static final MyClass instance = new MyClass();
private MyActivity myActivity;
private Button button;
private MyClass(){};
public void initialize(MyActivity activity){
myActivity = activity;
}
public void releaseMemory(){
instance = null; //Can't make it null
//Can do for individual variables
myActivity = null;
button = null;
}
}
在這種方法中,由於MyClass實例是最終的,因此我不能將其設置為null,而可以將單個變量設置為null。
那么我的理解是正確的還是我缺少與內存泄漏有關的任何內容?
第一個問題,為什么需要在Activity
對象上保留引用?
對於大多數用法,您只需要一個Context
對象。 因此,如果您想避免泄漏您的Activity
請養成以下習慣:
private MyActivity myActivity;
public void initialize(MyActivity activity){
myAcitivity = activity;
}
與:
private Context myContext;
public void initialize(Context context){
myContext = context.getApplicationContext();
}
由於Activity是Context的實現,因此您的代碼應保持正常運行。 方法getApplicationContext()
將始終返回一個應用程序上下文,您可以泄漏所有想要的內容。
現在,如果應用程序上下文還不夠,並且您確實需要一個Activity對象(如果您需要啟動其他Activity而不創建示例新任務),請首先問問自己為什么不能直接在Activity類中做到這一點。 如果不能,則可能是您在代碼體系結構方面做出了錯誤的決定。
如果您確實需要將Activity
對象存儲在其他對象(無論是否為單個)中,請記住,活動具有生命周期,並且您需要Activity
來通知MyClass
它不再可用(如果您沒有,並且忘記調用releaseMemory(),那么您的Activity
進入后台時將泄漏):
public class MyActivity {
MyClass myClass; // instance initialize somewhere in your code
onPause() {
myClass.setActivity(this);
}
onResume() {
myClass.setActivity(null);
}
}
public class MyClass {
@Nullable Activity myActivity; // tha @Nullable annotation helps you remember to do null checks before using this field.
public void setActivity(Activity activity) {
myActivity = activity;
}
}
如果您的MyClass
也是Fragment
,則可以在onAttach()
和onDetach()
方法中設置和釋放Activity
(這些方法由Android自動調用,因此您無需嘗試調用它們)在您的Activity
)。
最后,我建議不要使用第一個代碼示例,因為即使調用方法releaseMemory()
並確保對象A
沒有剩余引用,也無法采取任何措施來確保對象B
仍然沒有對象A
引用您的類MyClass
。
最終字段無法修改。 這就是存在final修飾符的原因。
您的單例的第二個版本在一致性方面更好。 但除非您關閉應用程序,否則它將永遠不會被gc'ed。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.