編輯:關於Android編程
一、概述
在Android的開發中,經常聽到“內存洩漏”這個詞。“內存洩漏”就是一個對象已經不需要再使用了,但是因為其它的對象持有該對象的引用,導致它的內存不能被回收。“內存洩漏”的慢慢積累,最終會導致OOM的發生,千裡之堤,毀於蟻穴。所以在寫代碼的過程中,應該要注意規避會導致“內存洩漏”的代碼寫法,提高軟件的健壯性。
本文將從發現問題、解決問題、總結問題的三個角度出發,循序漸進,徹底解決“內存洩漏”的問題。
二、內存洩漏的檢查工具Heap
工欲善其事必先利其器,要檢測“內存洩漏”的發生,需要借助DDMS中的Heap工具及MAT工具,Heap工具用於大致分析是否存在“內存洩漏”,而MAT工具則用於分析“內存洩漏”發生在哪裡。
Heap工具的使用介紹
具體操作
我們先模擬一下內存洩漏,然後通過Heap工具來判斷一下是否存在內存洩漏。
上一段存在內存洩漏的代碼:
public class LeakAty extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.aty_leak); testLeak(); } /** * 測試內存洩漏的代碼 */ private void testLeak() { new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }
上述的代碼存在內存洩漏,new Runnable(){}是一個非靜態的匿名內部類,所以它會強引用創建它的外圍對象LeakAty,我們來測試一下內存洩漏的過程,開啟手機的方向旋轉功能,不斷地旋轉手機,讓LeakAty不斷地創建新的實例。理論上如果不存在上述洩漏的代碼,之前的Activity會在onDestory之後被回收內存。而一旦存在上述洩漏的代碼,新創建的Ruannale實例會一直處於運行狀態,它不會被回收,而它強引用的LeakAty當然也不會被回收,所以在屏幕不斷旋轉,之前創建的LeakAty就不會被釋放,會導致旋轉n次,內存中就存在n+1個的LeakAty實例。
Heap工具第一次按下Cause GC按鈕的截圖:
上圖的data object的Total Size的大小為1.031M。經過多次的旋轉屏幕之後,我們再看一下截圖
Total Size變成了2.059M,從1.031M到2.059M,每次調用GC的過程中data object的總大小沒有回落,所以可以證實上面的代碼確實是存在內存洩漏的問題,那麼洩漏發生在哪裡?答案可以通過MAT工具來分析得到。
三、內存洩漏的分析工具MAT
要通過MAT分析,需要提供一個.hprof文件。我們可以通過”Dump HPROF file”按鈕轉存當前的堆內存信息。我們將其保存為1.hprof。
導出的1.hprof的格式需要通過..\sdk\tools\目錄下的hprof-conv.exe工具進行轉換才能被MAT成功導入,我們將其轉換成out1.hprof
將out1.hprof導入到MAT工具中,File->Open Heap Dump…
點擊左邊的標簽Overview,Actions->Histogram
在Histogram界面中,因為我們想要知道Activity是否洩漏了,所以輸入關鍵詞Activity,然後按下回車鍵。
之後便可以得到Activity的相關的搜索結果,下圖的搜索結果中Activity的實例有7個。點擊選中下圖標紅色框框的地方,右鍵->Merge Shortest Paths to GC Roots->exclude all phantom/weak/soft etc. references。排除虛引用、弱引用、軟引用的實例,剩下的都是強引用實例。
從過濾出來的強引用的列表中,我們可以看到這七個實例都是被Thread所引用了。所以證實上面的代碼確實存在內存洩漏。
四、本文總結
內存洩漏檢測可以使用Heap工具,內存分析可以使用MAT工具。本文的案例中提到了一種內存洩漏的情況,就是非靜態內部類的對象會強引用其外圍對象,一旦這個非靜態內部類的實例沒有釋放,它的外圍對象也不會釋放,所以就會造成內存洩漏。下篇將具體探討一下,在Android的開發過程中,哪些寫法容易造成內存洩漏,該如何解決?請閱讀Android內存洩漏終極解決篇(下)。
以上就是本文的全部內容,希望大家喜歡。
本文是想總結一些Android Studio的使用技巧,對於大多數習慣了使用eclipse的人來說,可能會需要一段時間,但是如果看過下面的一些介紹,你就能體會到Andr
聯系人提供程序是一個強大而又靈活的 Android 組件,用於管理設備上有關聯系人數據的中央存儲庫。 聯系人提供程序是您在設備的聯系人應用中看到的數據源,您也可以在自己的
1 背景上路了,准備開始重操那兩年的舊業,後悔之前在上家公司做Amlogic和Realtak方案盒子時沒有養成寫博客的習慣,這算是開篇之作吧,順帶也算是給一個網友的答疑吧
什麼是Context?一個Context意味著一個場景,一個場景就是我們和軟件進行交互的一個過程。比如當你使用微信的時候,場景包括聊天界面、通訊錄、朋友圈,以及背後的一些