內存泄漏與內存溢出
阿新 • • 發佈:2018-07-29
hash tag 最終 對象引用 變化 申請 close hashcode mem
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;
內存泄露 memory leak,是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積後果很嚴重,無論多少內存,遲早會被占光。
## memory leak會最終會導致out of memory!
內存泄漏
長生命周期的對象引用短聲明周期的對象,導致短生命周期的對象在生命周期已結束後還無法回收對象內存 ,造成內存泄漏
場景
- 1、靜態集合引用對象
public class dome1 { static Set<Object> s = new HashSet(10); public static void main(String[] args) { for (int i = 0; i < 100; i++) { Object o = new Object(); s.add(o); //對象賦值位空值,理應被垃圾回收器回收,但是被集合引用, // 但是GC-Roots 到對象之間存在引用鏈(可到達), //所以不會被回收內存 o = null; } s.forEach(System.out::println); } }
- 2、集合裏面的對象屬性被修改,在調用remove()方法時不起作用,造成對象刪除不掉,造成內存泄漏
HashSet<Person> set = new HashSet<>(); Person tom = new Person(1L, "Tom", 12); System.out.println(tom.hashCode());//2613467 set.add(tom); tom.setAge(13);//修改對象的屬性後對象的hashCode發生變化 System.out.println(tom.hashCode());//2613468 System.out.println(set.remove(tom));//false remove不成功,造成內存泄漏 set.forEach(System.out::println); System.out.println(set.add(tom));// true 添加成功,判斷是否相等時驗證hashCode set.forEach(System.out::println);
3、監聽器未刪除
4、各種連接為關閉
數據庫鏈接、網絡鏈接、IO鏈接必須顯式的調用close關閉鏈接,否則不會被GC回收
5、內部類和外部模塊的引用
- 6、單例模式引用其他對象
單例模式為靜態資源,整個JVM生命周期都有效,如果單例對象持有對外部對象的引用,那麽這個外部對象不會被GC回收,導致內存泄漏
if (true){ Person tom = new Person(1L, "Tom", 12); singleton.getInstance().setPerson(tom); } System.out.println(singleton.getInstance().getPerson());
對象tom已經結束生命周期,但是被單例對象引用,不會被GC回收
二、內存溢出
在Java堆中不斷的創建對象造成
大量的內存泄漏
內存泄漏與內存溢出