Effective Java Item7 移除不需要的物件引用
整理Effective Java書中Item 7: Eliminate obsolete object references心得筆記
主旨
由於Java有GC的機制,很多時候開發者不會考慮到記憶體管理或著覺得不需要考慮,這是錯誤的觀念,如果忽略可能導致潛在memory leak問題,必須重視。
點出問題
- array
這個蠻經典的範例在ArrayList原始碼中,調用remove後,關鍵就在elementData[--size] = null;這行進行釋放,如果沒有這行GC不會知道要處理。
- caches
我們常會將很多不同的資料放到cache裡面,但過些時間後又沒有定期清理,很容易就把資料忘在裡面,即使已經不在使用了。如果是這總狀況可以使用WeakHashMap來當cache的map。存在這個map的值如果已經沒有任何外部引用將自動被刪除。這裡的Weak指的就是弱引用,表示若沒有任何引用當GC執行後就馬上就被清理。可以跑跑看下面範例。
- listeners and other callbacks
假如你在總公司提供了一個簡單的推送API服務,集團會員登入上線會自動註冊你的服務,會員就可以收到總公司的推送消息。一開始沒什麼問題,使用時間久了後發現server負擔越來越大導致OOM,一時也找不出原因只能先靠重啟暫時解決問題,這樣類似的問題困擾著很多開發者又不得其門而入。這個例子其實很多會員下線了以後服務根本不知道,也沒有進行取消註冊服務,導致最後服務每次都要一直大量推送資料給沒有在線的會員。
小結
記憶體洩漏的問題通常不會表現得很明顯,都會在某個壓力峰值或著某個特別的操作爆發,它們可能在系統裡面是一顆多年的毒瘤,目前的解決方法不外乎是仔細的進行code review以及小規模的重構系統,或著透過分析工具來檢測系統。
參考延伸閱讀:
Read other posts