內(nèi)存泄露常見來(lái)源:
一、過(guò)期引用
元素出棧,忘記設(shè)置為Null:

如果一個(gè)棧先是增長(zhǎng),然后再收縮,從棧中彈出來(lái)的對(duì)象不會(huì)被當(dāng)作垃圾回收,即使使用棧的程序不再引用這些對(duì)象,它們也不會(huì)被回收。因?yàn)闂?nèi)部維護(hù)著對(duì)這些對(duì)象的過(guò)期引用(obsolete reference)。指永遠(yuǎn)也不會(huì)再被解除的引用。
在本例中,在elements數(shù)組的“活動(dòng)部分(active portion)”之外的任何引用都是過(guò)期的。活動(dòng)部分指elements中下標(biāo)小于size的那些元素。
解決方法:清空引用。元素被彈出棧,指向它的引用就過(guò)期了。修改如下:

清空好處:如果它們以后又被錯(cuò)誤地解除引用,程序拋出NullPointerException異常
最好的方法:讓包含該引用的變量結(jié)束其生命周期。如果在最緊湊的作用域范圍內(nèi)定義每一個(gè)變量(見第45條),這種情形會(huì)自然而然地發(fā)生。
只要類是自己管理內(nèi)存,程序員就應(yīng)該警惕內(nèi)存泄漏問(wèn)題。一旦元素被釋放掉,該元素中包含的任何對(duì)象引用都應(yīng)該被清空。
二、緩存。
只要在緩存之外存在對(duì)某個(gè)項(xiàng)的鍵的引用(外部代碼沒(méi)有持有m中的一個(gè)鍵的引用),該項(xiàng)就有意義;如果沒(méi)有,可以使用WeakHashMap來(lái)代表緩存。過(guò)期則清空

三、監(jiān)聽器和其他回調(diào)。

AppCompatActivity實(shí)現(xiàn)一個(gè)接口OnNetworkChangedListener,用來(lái)監(jiān)聽網(wǎng)絡(luò)的變化。然后,把這個(gè)監(jiān)聽器注冊(cè)到NetworkManager實(shí)例中。
NetworkManager實(shí)例持有監(jiān)聽器(MainActivity是實(shí)現(xiàn)者,指向MainActivity對(duì)象的引用)。
當(dāng)NetworkManger實(shí)例的生命周期比MainActivity長(zhǎng),當(dāng)MainActivity銷毀時(shí)(比如屏幕發(fā)生旋轉(zhuǎn)),NetworkManager實(shí)例還沒(méi)有銷毀,它持有指向MainActivity對(duì)象的引用。系統(tǒng)回調(diào)MainActivity的onDestroy方法,這時(shí),GC是要回收MainActivity對(duì)象的,但是,MainActivity對(duì)象依然可達(dá)(NetworkManager實(shí)例持有指向MainActivity對(duì)象的引用),所以沒(méi)有回收,MainActivity對(duì)象泄露。
解決辦法:

https://www.cnblogs.com/WJQ2017/p/7634330.html
https://www.cnblogs.com/ttylinux/archive/2017/03/12/6536929.html