在Android開發過程當中,咱們常常碰到的狀況就是在咱們不清楚爲何狀況下,程序忽然出現Crash了。其中有一類日誌相信你們都常常碰到過,這類日誌就是OOM相關的日誌。這類日誌除了咱們知道的Bitmap操做的時候會常常致使,還有一種隱藏的較深的緣由就是內存泄露(Memory Leak)。編輯器
推薦使用 LeakCanary 工具來檢測應用程序是否存在內存泄露。LeakCanary是由 Square 開源的一款輕量級的第三方內存泄漏檢測工具,當檢測到程序中產生內存泄漏時,它將以最直觀的方式告訴咱們哪裏產生了內存泄漏和致使誰泄漏了而不能被回收。工具
單例的靜態特性使得其生命週期和應用的生命週期同樣長。
如圖,咱們先聲明一個單例對象:
而後在Activity使用的時候,習慣性的傳一個this:
集成了LeakCanary後測試,發現內存泄露了:
解決方案:
通常狀況下,改爲以下圖的寫法就能夠了,由於單例的生命週期和應用的同樣長,這樣就防止了內存泄漏。:
總結:單例模式形成泄漏的緣由是擁有更長生命週期的對象持有短生命週期對象的強引用。測試
通常狀況下,容易產生內存泄露的資源主要爲:File,Cursor,Stream,Bitmap,BroadcastReceiver等,這些資源在使用時建議及時關閉,不然當這些資源沒有及時回收的時候,內存泄露也就產生了。針對這些資源使用,給以下建議:this
在咱們使用Handler的時候,常常看到編輯器提示咱們Handler可能會形成內存泄露,通常在這種狀況下,咱們能夠將Handler獨立出來或者使用靜態內部類,這樣能夠避免內存泄露。
這樣作的緣由是:非靜態內部類會潛在的持有它所屬的外部類的引用,可是靜態內部類是不會的。日誌
咱們可使用WeakReference來規避好多潛在的內存泄露的問題,可是並不代表WeakReference就是解決內存泄露的金鑰匙。是否使用WeakReference主要取決於對當前對問題的理解,這須要咱們對問題的的建模思想。對象