2017-01-02 169 views
1

我在用Android數據綁定試驗MVVM。我的代碼如下:避免內存泄漏的好方法

public class ... extends Activity {  
     ...    
     private CommentViewModel viewModel; 

     @Override 
     protected void onCreate(@Nullable Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      binding = DataBindingUtil.setContentView(this, provideLayout()); 
      viewModel = new CommentViewModel(this); 
      binding.setViewModel(viewModel); 
     } 

     @Override 
     protected void onDestroy() { 
      viewModel = null; //setting view model to null to avoid leaks 
      super.onDestroy(); 
     } 
} 

我試圖做的是,在我的onDestroy()設置ViewModel爲null,以避免任何可能的泄漏。

正如我ViewModel自己註冊一些callbacks與其他成分,並使用context如果不去除,上下文傳遞的地方,我決定將它設置爲空的回調的一個可能泄漏。

但是我的同事開了一個有趣的討論,他說這是一個過時的做法,正如'Effective Java'所暗示的,這就是你在C++中的做法。他說,一個好方法是從ViewModel中刪除所有回調,而不是將其設置爲空。例如:

public class ... extends Activity {  
     ...    
     private CommentViewModel viewModel; 

     @Override 
     protected void onCreate(@Nullable Bundle savedInstanceState) { 
      ...//same as above 
     } 

     @Override 
     protected void onDestroy() { 
      viewModel.removeCallbacks(); //removing all callbacks from view model to avoid leaks 
      super.onDestroy(); 
     } 
} 

現在這兩種方法都能正常工作,但在第一種方法中,我非常確信泄漏不會發生。但結果是,它看起來有些醜陋。第二種方法工作正常,但它迫使我想想在ViewModel中可能發生的所有可能的泄漏。

這可能是一個普遍的問題:您認爲哪種方法更好,爲什麼?

回答

0

一般來說讓JVM做它的工作。

沒有什麼比東西更刺激喜歡

System.gc() 

在大型應用的產品代碼。這是中間件工程師調整JVM以及內存管理的工作 - 而且我真的是這些人中的一員。在你的情況下,事情是一樣的,開發Android的人最清楚如何在其中管理GC。如果它不會使任何東西變得更清晰/更容易理解,則不應編寫更多代碼。

在另一方面

Expirienced程序員應該知道所有與框架連接搞鬼(例如:stackoverflow.com/questions/13534030/can-a-scheduled-future-cause-a-memory-leak)以及如何不取消,不解除引用,不關閉等可能會導致內存泄漏。

你的情況可能更重要的是,你可以想象會有相當複雜的回調(假設它們是循環的並且有數千個回調),並且讓你的引用null不會做任何事情GC更容易,但刪除回調將。

+0

「使您的引用null不會讓GC更容易,但刪除回調會。」 - 你能解釋一下嗎?我不明白。兩者不是一回事嗎? –