前段時間開發的Android應用,每次都是在運行了半個小時左右後突然掛掉了,很是莫名其妙,也不知道哪裡出了問題,後來一步步排查,發現問題出在JNI層,一個被頻繁調用的函數分配的內存忘記釋放,導致內存洩漏。
這次問題使我明白,別以為Android程序是基於Java語言,有強大的垃圾回收機制,就完全不用擔心內存問題,其實Android程序也要特別小心你的內存,因為畢竟手機不比PC機,內存是極其有限的,在內存不夠的時候,系統隨時會Kill掉你的程序。目前我所了解到的,容易發生內存問題的地方如下:
(1) 操作Bitmap對象,一定要注意,在不使用的時候 recycle
(2) 訪問數據庫,一定要記得關閉游標
(3) 涉及JNI層的代碼,由於JNI層是采用C/C++編寫,需要自己管理內存的分配/回收,所以要慎重小心。
那麼,Android開發中,有什麼有效的方法可以檢測內存使用情況以及內存洩漏呢?
這裡主要介紹三種方法:
1. 程序的Log信息
程序在進行垃圾回收的時候,會打印一條Log信息(logcat窗口),例如:
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
注意這條信息中的 “ 3571K/9991K” 值,這代表著程序使用的heap大小,如果這個值一直在增加,而從來不減小,那麼就代表著你的程序存在著內存洩漏。
2. DDMS的Heap信息
Eclipse開發環境還提供了一種更加直觀的方法來查看App的Heap信息,操作方式如下:
(1) 連接手機,運行程序,假設是 com.ticktick.test 程序
(2) 點擊DDMS按鈕,在左側的Device窗口選中你要檢測的程序(com.ticktick.test )
(3) 點擊Device窗口工具欄的第二個圖標(Update Heap),
(4) 點擊右邊的窗口的Cause GC按鈕,即可得到當前程序的Heap信息
同樣,隨著程序的運行,多次點擊得到的Heap大小,如果只增不減的話,也昭示著你的程序有內存洩漏。
3. adb命令查看內存信息
其實,最全面最簡單的方式還是用adb命令來查看程序的內存占用和內存洩漏情況,打開命令行窗口,adb命令的格式如下:
adb shell dumpsys meminfo <package_name>
其中,package_name 也可以換成程序的pid,pid可以通過 adb shell top | grep app_name 來查找,在命令行窗口運行上述命令,得到的我的 com.ticktick.test 程序的內存情況如下所示:
這裡得到的信息非常多,重點關注如下幾個字段:
(1) Native/Dalvik 的 Heap 信息
具體在上面的第一行和第二行,它分別給出的是JNI層和Java層的內存分配情況,如果發現這個值一直增長,則代表程序可能出現了內存洩漏。
(2) Total 的 PSS 信息
這個值就是你的應用真正占據的內存大小,通過這個信息,你可以輕松判別手機中哪些程序占內存比較大了。
4. 總結
關於Android開發中內存的使用情況和內存洩漏的檢測就簡單介紹到這裡,基本上用以上三種方式都能夠定位內存洩漏問題,平時在使用Bitmap,數據庫和JNI層C/C++編程的時候,注意一點就行。另外,如果想深入了解文中的一些詳細內容,可以參考Google官方提供的兩篇文章,它們有著更詳細的論述《Investigating Your RAM Usage》,《Managing Your App Memory》,有任何疑問或者不清楚的地方,歡迎留言或者來信[email protected]交流。
更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11