① 如何使用MAT分析android應用內存泄露
使用Android Studio,Android Device Monitor 配合Eclipse的MAT(
Memory Analyzer)工具來分析android內存泄露。
新建一個Android 測試應用。填寫好應用的名稱,以及保存位置後,直接下一步到最後點擊「Finish」。
② Android開發中,有什麼工具能夠排查jni層的內存泄漏
(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/K, 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 mpsys 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 內存泄漏
1.使用eclipse 自帶的 DDMS 工具分析各線程的內存使用情況,如下圖所示
Heap視圖界面會定時刷新,在對應用的不斷的操作過程中就可以看到內存使用的變化。
2.判斷當前進程是否有內存泄漏。
需要注意一個值:VM Heap頁面中部有一個data object選項,即數據對象,也就是我們的程序中大量存在的類類型的對象。
在data object一行中有一列是「Total Size」,其值就是當前進程中所有Java數據對象的內存總量,一般情況下,這個值的大小決定了是否會有內存泄漏。
3可以據下面狀態判斷內存有泄漏:
1) 不斷的操作當前應用,或者重復某一動作,注意觀察data object的Total Size值。
2) 正常情況下Total Size值都會穩定在一個有限的范圍內,也就是說如果程序中的的代碼邏輯良好,沒有創建的對象不被GC機制正常回收的情況,即便不斷的操作生成很多對象,而在虛擬機不斷的進行垃圾回收的過程中,這些對象都被正常回收了,內存使用量會保持在一個比較穩定的水平。
3) 如果代碼中存在對象引用沒有釋放的情況,則data object的Total Size值在每次GC後不會有明顯的回落,隨著操作次數的增多Total Size的值會越來越大。
④ 如何用MAT分析Android應用內存泄露
Android應用內存泄漏的的原因有以下幾個:1查詢資料庫後沒有關閉游標cursor2構造Adapter時,沒有使用convertView重用3Bitmap對象不在使用時調用recycle()釋放內存4對象被生命周期長的對象引用,如activity被靜態集合引用導致activity不能釋放內存泄漏的發現:通過DDMS中的heap工具,去發現是否有內存溢出。內存泄漏如何解決:通過內存分析工具MAT(MemoryAnalyzerTool),找到內存泄露的對象
⑤ 常見的內存泄漏原因及解決方法
(Memory Leak,內存泄漏)
當一個對象已經不需要再使用本該被回收時,另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。
內存泄漏是造成應用程序OOM的主要原因之一。我們知道Android系統為每個應用程序分配的內存是有限的,而當一個應用中產生的內存泄漏比較多時,這就難免會導致應用所需要的內存超過系統分配的內存限額,這就造成了內存溢出從而導致應用Crash。
因為內存泄漏是在堆內存中,所以對我們來說並不是可見的。通常我們可以藉助MAT、LeakCanary等工具來檢測應用程序是否存在內存泄漏。
1、MAT是一款強大的內存分析工具,功能繁多而復雜。
2、LeakCanary則是由Square開源的一款輕量級的第三方內存泄漏檢測工具,當檢測到程序中產生內存泄漏時,它將以最直觀的方式告訴我們哪裡產生了內存泄漏和導致誰泄漏了而不能被回收。
由於單例的靜態特性使得其生命周期和應用的生命周期一樣長,如果一個對象已經不再需要使用了,而單例對象還持有該對象的引用,就會使得該對象不能被正常回收,從而導致了內存泄漏。
示例:防止單例導致內存泄漏的實例
這樣不管傳入什麼Context最終將使用Application的Context,而單例的生命周期和應用的一樣長,這樣就防止了內存泄漏。???
例如,有時候我們可能會在啟動頻繁的Activity中,為了避免重復創建相同的數據資源,可能會出現如下寫法:
這樣在Activity內部創建了一個非靜態內部類的單例,每次啟動Activity時都會使用該單例的數據。雖然這樣避免了資源的重復創建,但是這種寫法卻會造成內存泄漏。因為非靜態內部類默認會持有外部類的引用,而該非靜態內部類又創建了一個靜態的實例,該實例的生命周期和應用的一樣長,這就導致了該靜態實例一直會持有該Activity的引用,從而導致Activity的內存資源不能被正常回收。
解決方法 :將該內部類設為靜態內部類或將該內部類抽取出來封裝成一個單例,如果需要使用Context,就使用Application的Context。
示例:創建匿名內部類的靜態對象
1、從Android的角度
當Android應用程序啟動時,該應用程序的主線程會自動創建一個Looper對象和與之關聯的MessageQueue。當主線程中實例化一個Handler對象後,它就會自動與主線程Looper的MessageQueue關聯起來。所有發送到MessageQueue的Messag都會持有Handler的引用,所以Looper會據此回調Handle的handleMessage()方法來處理消息。只要MessageQueue中有未處理的Message,Looper就會不斷的從中取出並交給Handler處理。另外,主線程的Looper對象會伴隨該應用程序的整個生命周期。
2、 Java角度
在Java中,非靜態內部類和匿名類內部類都會潛在持有它們所屬的外部類的引用,但是靜態內部類卻不會。
對上述的示例進行分析,當MainActivity結束時,未處理的消息持有handler的引用,而handler又持有它所屬的外部類也就是MainActivity的引用。這條引用關系會一直保持直到消息得到處理,這樣阻止了MainActivity被垃圾回收器回收,從而造成了內存泄漏。
解決方法 :將Handler類獨立出來或者使用靜態內部類,這樣便可以避免內存泄漏。
示例:AsyncTask和Runnable
AsyncTask和Runnable都使用了匿名內部類,那麼它們將持有其所在Activity的隱式引用。如果任務在Activity銷毀之前還未完成,那麼將導致Activity的內存資源無法被回收,從而造成內存泄漏。
解決方法 :將AsyncTask和Runnable類獨立出來或者使用靜態內部類,這樣便可以避免內存泄漏。
對於使用了BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等資源,應該在Activity銷毀時及時關閉或者注銷,否則這些資源將不會被回收,從而造成內存泄漏。
1)比如在Activity中register了一個BraodcastReceiver,但在Activity結束後沒有unregister該BraodcastReceiver。
2)資源性對象比如Cursor,Stream、File文件等往往都用了一些緩沖,我們在不使用的時候,應該及時關閉它們,以便它們的緩沖及時回收內存。它們的緩沖不僅存在於 java虛擬機內,還存在於java虛擬機外。如果我們僅僅是把它的引用設置為null,而不關閉它們,往往會造成內存泄漏。
3)對於資源性對象在不使用的時候,應該調用它的close()函數將其關閉掉,然後再設置為null。在我們的程序退出時一定要確保我們的資源性對象已經關閉。
4)Bitmap對象不在使用時調用recycle()釋放內存。2.3以後的bitmap應該是不需要手動recycle了,內存已經在java層了。
初始時ListView會從BaseAdapter中根據當前的屏幕布局實例化一定數量的View對象,同時ListView會將這些View對象緩存起來。當向上滾動ListView時,原先位於最上面的Item的View對象會被回收,然後被用來構造新出現在下面的Item。這個構造過程就是由getView()方法完成的,getView()的第二個形參convertView就是被緩存起來的Item的View對象(初始化時緩存中沒有View對象則convertView是null)。
構造Adapter時,沒有使用緩存的convertView。
解決方法 :在構造Adapter時,使用緩存的convertView。
我們通常把一些對象的引用加入到了集合容器(比如ArrayList)中,當我們不需要該對象時,並沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。
解決方法 :在退出程序之前,將集合里的東西clear,然後置為null,再退出程序。
當我們不要使用WebView對象時,應該調用它的destory()函數來銷毀它,並釋放其佔用的內存,否則其長期佔用的內存也不能被回收,從而造成內存泄露。
解決方法 :為WebView另外開啟一個進程,通過AIDL與主線程進行通信,WebView所在的進程可以根據業務的需要選擇合適的時機進行銷毀,從而達到內存的完整釋放。
1、在涉及使用Context時,對於生命周期比Activity長的對象應該使用Application的Context。凡是使用Context優先考慮Application的Context,當然它並不是萬能的,對於有些地方則必須使用Activity的Context。對於Application,Service,Activity三者的Context的應用場景如下:
其中,NO1表示Application和Service可以啟動一個Activity,不過需要創建一個新的task任務隊列。而對於Dialog而言,只有在Activity中才能創建。除此之外三者都可以使用。
2、對於需要在靜態內部類中使用非靜態外部成員變數(如:Context、View ),可以在靜態內部類中使用弱引用來引用外部類的變數來避免內存泄漏。
3、對於不再需要使用的對象,顯示的將其賦值為null,比如使用完Bitmap後先調用recycle(),再賦為null。
4、保持對對象生命周期的敏感,特別注意單例、靜態對象、全局性集合等的生命周期。
5、對於生命周期比Activity長的內部類對象,並且內部類中使用了外部類的成員變數,可以這樣做避免內存泄漏:
1)將內部類改為靜態內部類
2)靜態內部類中使用弱引用來引用外部類的成員變數
Android內存泄漏總結
⑥ Android studio如何分析內存泄漏,是否有自帶的分析工具
通過分析內存堆積面積圖,可以知道內存分配與回收的趨勢。通過比較某個(某一系列)操作前後的內存大小,可以粗略判斷是否有內存泄漏的情況。
AndroidStudio也有Device Monitor,也提供內存監測工具 Heap,可以使用 Heap 監測應用進程使用內存情況。
⑦ Android studio如何分析內存泄漏,是否有自帶的分析工具
AndroidStudio也有DeviceMonitor,也提供內存監測工具Heap,可以使用Heap監測應用進程使用內存情況。
⑧ Android studio如何分析內存泄漏,是否有自帶的分析工具
Android studio是沒有自帶這個工具的,不能分析內存泄露。你需要用已經ROOT過的真機來獲取APP運行過程中的內存信息,這需要你獲取該手機的最高許可權。如果沒有這樣的手機,或者沒有相應的機型,你可以去testbird上面試試雲手機吧,上面的手機都是開放最高許可權的,而且機型很全,,,
⑨ Android studio如何分析內存泄漏,是否有自帶的分析工具
Android內存分析工具
Memory Monitor
GC操作需要暫停其他線程,因此短時間頻繁的GC會對UI線程產生影響,導致頻繁GC一般有兩種情況,
大量的對象被創建又在短時間內馬上被釋放,比如在View的onDraw方法中創建對象
Young Generation的內存區域達到閥值,剩餘空間不夠的時候,也會觸發頻繁GC
Android Studio提供了Memory Monitor來實時顯示應用運行時內存佔用情況,下邊藍色部分是現在佔用的內存,上麵灰色的部分顯示是已回收的內存。如果在圖上看到尖峰,也就是快速分配內存又被回收,也就是發生了內存抖動,這里就是需要優化的地方。