1.如何去優化自己現有的項目,運行更加流暢
單個app進程 會根據手機性能分配不同的內容如: 8m 16m 32m 64m
2.當然最好的是在開發項目是就避免內存泄漏
在android應用層開發的時候,主要還是對java層的內存進行分析
( 而c 和c++,是自己去分配內存和釋放內存 -- 手動管理 malloc free)
3.內存泄漏:內存不在掌控之內,當一個對象已經不需要使用了,本該回收時,而有另一個正在使用的對象持有它的引用,從而導致對象不能被回收而停留在堆內存中,這樣就產生了內存泄漏。
4.java 中GC也會占用CPU性能而大量的分配內存和GC回收的話,就會造成GC抖動,一樣會使應用變卡,所以,我們也一樣要避免。
5.了解Java回收機制,對象不再有任何的引用的時候,才會被GC回收。
靜態的:
在程序編譯時就已經分配好,這塊的內存在程序整個運行期間都一直存在
存放的是靜態數據。全局的static數據和常量
棧式的
存放了編譯器可知的各種基本數據類型,(boolean byte,char,short,int,float,long,double)對象的引用(reference引用指針),
在執行函數(方法)時,函數的一些內部變量
堆內存
存放的是對象實例,動態內存分配,java中直接依賴GC機制
StrongReference:
回收時機:從不回收,使用:對象一般保存,生命周期:JVM停止的時候才會終止
SoftReference :
回收時機:到內存不足的時候,使用:SoftReference<String>結合ReferenceQueue構造有效期短;生命周期:內存不足時終止
WeakReference:
回收時機:在垃圾回收的時候,使用:同軟引用,生命周期:GC后終止
PhatomReference:
回收時機:在垃圾回收的時候,合ReferenceQueue來跟蹤對象被垃圾回收期回收的活動;生命周期:GC后終止
開發時:為了防止內存溢出,處理一些比較占用內存大并且生命周期長的對象的時候,可以盡量使用軟引用和弱引用。
1.使用Android Monitor:
可以看右邊兩個顏色塊的說明:
Allocated :代表已被分配的
Free: 代表沒有被使用的內存
在Memory 有個卡車的標志 Initiate GC,代表手動GC按鈕,而一般檢測一個activity是否有內存泄漏的時候,是先記錄當前的內存分配情況,然后打開需要檢測的activity,進行一系列操作后關閉后GC,再次記錄對比之前記錄的情況,如果內存大于之前的值,則代表有內存泄漏,分析代碼。
Dump Java Heap
基本在點擊這個按鈕之前,我一般會先GC下,這樣可以減少無用的對象,在點擊這個按鈕后,耐心等待一會,就會發現有生成一個hprof文件,由此記錄對比分析。基本可以解決大部分的OOM。
Start Allocation Tracking
這個主要是對各個線程作分析,使用方法先點擊一次然后進行想檢測的操作,最后在點擊一次結束,然后找到自己想檢測的方法,可以查看對應的方法,分析內存情況。
當app退出的時候,這個進程里面所有的對象應該就都被回收了,尤其是很容易被泄露的(View,Activity)是否還內存當中。
可以讓app退出以后,查看系統該進程里面的所有的View、Activity對象是否為0.
工具:使用AndroidStudio--AndroidMonitor--System Information--Memory Usage查看Objects里面的views和Activity的數量是否0.
2.MAT 使用Eclipse插件 Eclipse Memory Analyzer
首先在運行時,參照上面使用Android Monitor,找到點擊Dump Java Heap生成的文件,可以點擊右邊的Captures,右鍵點擊Export to standard .hprof 文件,然后使用 Eclipse Memory Analyzer工具點File選擇 open Heap dump ,將對應的文件導入,選擇 Leak Suspect Report ,自動檢查這個dump堆可能泄露的地方,給出報告對象的存活和為什么他們還沒有被垃圾回收器回收掉。
現在大概介紹下 Eclipse Memory Analyzer的幾個模塊
action模塊下:
Histogram:柱狀圖,列舉了每個class中對象的實例
Dominator Tree :支配樹 列舉了存活著的最大的對象
Top Consumers: 高級用戶:圓形圖打印最大的對象
Duplicate Classes:重復的類 檢測由多個類裝載器加載的類。
report 模塊下:
Leak Suspect 泄漏懷疑 包含了可能泄漏的和系統的概況
Top Componments 頂部組件:組件的列表報告大于總堆的1%。
1.懷疑對象
1)步驟記錄,首先打開記錄的文件。然后下面任務欄中的Navigation中的點擊histogram右鍵選擇add to Compare Basket,記得將兩個文件都添加都Compare Basket
切換到Compare Basket,就可以看到兩個histogram,點擊!就會出現Compared Tables ,這里就有兩個對象個數的對比結果。然后具體對象的對比,還有就是Shallow Heap和對象占用內存的對比
2)MAT對比操作前后的hprof來定位內存泄漏,bar欄上找到Group by... 的一個按鈕,上面有一個Group By package,輸入自己的包名,這樣就可以找到自己寫的代碼的對象個數及堆棧大小。
2.MAT分析hprof來定位內存泄漏原因所在。
1)Dump出內存泄漏當時的內存鏡像hprof,分析懷疑的類
2)把上面得出的這些對象逐一排查,
(1)進入histogram,過濾出某一個嫌疑對象的類
(2)然后分析持有改類對象引用的外部對象(在該類上面點擊List Object--->with incoming references )
(3)過濾其他引用 (在類上面點擊右鍵Merge Shortest Paths to GC Roots--->exclude all phantom/weak/soft etc.references)
(4)逐個分析每個對象的GC路徑是否正常,此時就要進入代碼分析此時這個對象的引用持有是否合理。
總結,容易出現內存泄漏幾種情況
單例傳入Context
接口監聽 getViewTreeObserver
InputMethodManager
多線程
停止動畫
Handler
性能優化的工具:
Android monitor
Allaction Tracking: 追蹤內存分配信息。可以很直觀的看到某個操作的內存是如何進行分配
打開Android Device Monitor 找到Allaction Tracking ,點擊StartTracking ,執行手機操作,點擊GetAllocation
當然這個不打開Android Device Monitor使用android Monitor也是可以的,Android Monitor則是點擊開始和結束,會自動生成一個.alloc文件。在左上角有點擊group by Methon &allocator 在后面又有一個塊狀的圓形圖就可以一個內存分配情況,當然也可以切換為柱狀圖,點擊自己想要的塊,然后就可以選取我們想要檢查的類
LeakCanary 直接可以在手機端查看內存泄露的工具
具體使用方法就不在此做詳細介紹了,在https://github.com/square/leakcanary 有比較詳細的介紹,使用也十分的簡單,只要在代碼中做好那些配置,可以關注下運行demo的app,自動會生成一個leaks的程序,在測試時,會自動收集程序中的內存泄露。并且記錄。記錄的都是對象對應的引用位置,可以具體查看代碼中的引用位置做分析
下面看一下LeakCanary的執行
我們是在Application install方法
會調用LeakCanary 中的 androidWatcher()方法然后進行如下的調用。
RefWatcher
new AndroidWatcherExecutor() --->dumpHeap()/analyze()(--->runAnalysis())--->Hprof文件分析
new AndroidHeapDumper()
new ServiceHeapDumpListener()
3.Lint分析工具
Inspect code 代碼檢測
檢測資源文件是否有沒有用到的資源。
檢測常見內存泄露
安全問題SDK版本安全問題
是否有費的代碼沒有用到
代碼的規范---甚至駝峰命名法也會檢測
自動生成的羅列出來
沒用的導包
可能的bug
這部分中具體的就不做介紹了,直接翻譯英文就基本可以理解
Specify Dependencies
在打開當前的類比如MainActivity,在選擇的時候,可以直接選的對應的類
查看當前的類中寫的引用
注:
Shallow Size
對象自身占用的內存大小,不包括它引用的對象。
針對非數組類型的對象,它的大小就是對象與它所有的成員變量大小的總和。當然這里面還會包括一些java語言特性的數據存儲單元。
針對數組類型的對象,它的大小是數組元素對象的大小總和。
Retained Size
當前對象大小+當前對象可直接或間接引用到的對象的大小總和。(間接引用的含義:A->B->C, C就是間接引用)
換句話說,Retained Size就是當前對象被GC后,從Heap上總共能釋放掉的內存。
不過,釋放的時候還要排除被GC Roots直接或間接引用的對象。他們暫時不會被被當做Garbage。