Effective Java代碼規則之七:消除過期的對象引用

  • 解釋

過期的對象引用指永遠也不會被解除的引用,這種引用將不會被垃圾回收,從而導致內存洩漏,嚴重的話將會導致內存耗盡,出現OutOfMemoryError 錯誤。出現內存洩漏的幾種可能:

1、無意識的對象引用

這種情況容易出現在數組和集合對對象的引用上,例如:

Object[] objectArrays = new Object[16];
String object1 = "Object1";
objectArrays[0] = object1;
object1 = null;//"Object1"這個對象並不能被回收,因為objectArrays持有對它的引用
List<object> objectList = new ArrayList<>();
String object2 = "Object2";
objectList.add(object2);
object2 = null;//"Object2"這個對象並不能被回收,因為objectList持有對它的引用
/<object>

消除以上引用的辦法就是顯式將objectArrays和objectList設成null。

2、緩存沒有清除

Map<string> maps = new LinkedHashMap<>();
String key = "key1";
Object object3 = "Object3";
maps.put(key, object3);
maps.remove(key);//如果不調用remove方法,Ojbect3對象將一直緩存在內存中
/<string>

3、資源沒有關閉

Java中的連接包括數據庫連接、網絡連接和io連接等等,如果沒有顯式調用其close()方法,是不會自動關閉的,我們應該在try代碼塊裡創建連接,在finally裡釋放連接,或者使用try-with-resource語法,就能夠避免此類內存洩漏。

4、監聽器或回調函數沒有刪除

如對某個控件添加單擊監聽器addOnClickListener(),但往往釋放對象的時候會忘記刪除監聽器,這就有可能造成內存洩漏。

  • 優點1:不會造成內存洩漏

及時消除過期的對象引用,不會造成內存洩漏。

  • 缺點1:過分清空對象引用是不可取的

清空對象引用應該是一種例外,而不是常態。消除過時引用的最佳方法是讓包含引用的變量超出其生命週期。

  • 最佳實踐

在實際工作中,如果發現內存洩漏,我們通常會使用工具進行排查,Jprobe、Jprofiler等收費工具功能強大,也可以使用JDK自帶的一些免費工具,比如:

jstat -gc <period> <times>, 可以顯示gc的信息,查看gc的次數,及時間。/<times>/<period>

Effective Java代碼規則之七:消除過期的對象引用

專業從事軟件研發工作多年,在軟件設計、開發、測試、研發管理等領域裡經驗豐富,感興趣的朋友可以關注我的頭條號,相信一定會有所收穫。

如果有軟件研發方面的問題,可以諮詢我。

謝謝!


分享到:


相關文章: