【JAVA】談談內存泄露

                                               談談內存泄露

應屆生面試中,常常被問到內存泄露,比方說什麼是內存泄露呀?造成內存泄露的情況等等。本菜今天就總結一下內存泄露方面的幾點小知識。

一、什麼是內存泄露

不再被使用的對象持續佔據內存,造成內存浪費的情形稱作內存泄露。這些對象被某些變量引用着,因此垃圾回收器無法回收它們。關於垃圾回收器如何判斷對象的存活狀態,請移步我的另外一篇文章【JAVA】如何判斷對象已經死亡?

當然引用類型也會對對象的生命週期造成影響,我的另外一篇文章【JAVA】java中的四種引用


二、造成內存泄露的情形及對應解決方案

【1】長生命週期的對象持有短生命週期對象的引用,就很有可能造成內存泄露。 

長生命週期的對象往往和整個程序的生命週期相同,若是當它們持有短生命週期的對象的引用,儘管短對象不再被使用,也無法被垃圾回收器回收,因爲垃圾回收器無法回收被強引用所關聯的對象。

解決方案:

(1)像一些靜態的集合類,它們的生命週期和整個程序相同,儘管放入集合中的元素不再需要,就算將元素強行置爲null,但由於集合類持有它們的引用,這些元素佔據的空間也得不到釋放,那麼在必要的時候,我們可以將集合類對象類型的變量置爲null。

(2)單例模式中,單例與整個程序的生命週期一致,如果單例對象持有其他短對象的引用,也很容易造成內存泄露,這還得靠我們謹慎編碼。

(3)又或是數據庫連接對象(長生命週期),ResultSet與Statement對象(短生命週期),連接不再被使用時,需要調用其close()方法,釋放長對象與短對象。同理,需要顯式調用close()方法的長生命週期的對象還有Socket、IO流、Session等。


【2】非靜態的外部類會隱式地持有外部類的一個強引用。

在Android中,如果在Activity內聲明一個非靜態的內部類,那麼只要該內部類沒有被回收的話,那麼外部類Activity就無法被回收,Activity所關聯的視圖和資源也不會被回收,這樣的內存泄露比較嚴重。

解決方案:

(1)將非靜態內部類改爲靜態內部類,靜態內部類屬於類,因此不會依賴與外部類的實例,從而不持有外部類實例的引用。

(2)顯式地聲明非靜態內部類持有外部類的一個弱引用,被弱引用關聯的對象,在下一次垃圾回收器活動時,就會被回收。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章