JVM垃圾收集機制-內存泄漏-內存溢出

JVM內存模型

在這裏插入圖片描述

環衛工人(垃圾回收器)

如下是C語言釋放內存空間的話比較複雜,容易出錯,沒有java開發有效率
在這裏插入圖片描述

如何發現垃圾?

原始方法:引用計數法
	--一個對象被賦值給一個變量時,引用計數+1;
	--持有引用的變量退出作用域時,引用計數-1.

在這裏插入圖片描述
但是如下比如說兩個對象引用(obj1,obj2)分別引用了實例1,實例2,實例1裏面的屬性又引用了實例2,實例2裏面的屬性又引用了實例1這個時候引用計數法的缺陷就表現出來了,比如代碼裏的作用域都結束了但兩個實例對象還在相互引用(這時這兩個對象應該已經是垃圾了,但是還存在相互關係就判斷不出來它是垃圾,不回收)

在這裏插入圖片描述

根搜索算法(GC Root)
	--棧幀裏的局部變量所引用的對象;
	--方法區的靜態變量和常量所引用的對象;

如下圖6個對象:
對象1的根在方法區不算垃圾
對象2的根在某個棧幀裏不算垃圾
對象4的根在方法棧裏不算垃圾
對象6沒有直接的根,但被非垃圾的對象4引用了所以它也不是垃圾
對象3被對象5引用了但對象5沒有根所以都是垃圾.
在這裏插入圖片描述

垃圾回收也要與時俱進

標記清除法
	黑色的是垃圾對象,綠色空白內存,灰色的非垃圾對象
	比較直接是垃圾對象就騰出來
	缺點:很多碎片,沒有連在一起,哪天我們要保存幾G的文件就悲劇了,看起來空閒空間挺大,放一個完整文件又放不進去.

在這裏插入圖片描述

分段複製算法
	用一半留一半,用起來效率比較高
	需要清理時,把需要存留的對象copy到下面那一半,然後把上面全清空

在這裏插入圖片描述

標記整理算法
	算法比較複雜,但比較靈活,效率也比較高
	儘量不往兩頭放,分配對象儘量往上面放,緊挨着
	每次回收就先整理一下,空白的一邊,用過的一邊,把不怎麼用的放前面
	不想分段算法那樣嚴格,因爲有時候可能已經用了一半多了.

在這裏插入圖片描述

分代收集算法
	伊甸園:西方故事裏人剛出生的地方(剛new出來的對象就放着裏面)
	生存區:又分From、To(分段法制法)
	From  :例如對象經歷了5次回收還沒被回收掉就證明它的生命週期應該比較長就把它放到From裏來
	老年代:回收15次後還存在就有很大機率會一直使用移到老年代裏來

在這裏插入圖片描述

如何編寫高效,健壯的Java程序

①:儘量不要在循環中使用try...catch、new對象
②:把頻繁使用的短命對象緩存起來
③:儘可能使用棧內變量(方法內局部變量)
④:不要用異常來控制代碼流程
⑤:用線程池、連接池,不要自己創建
⑥:學會讀Java核心API源代碼
⑦:推薦一本java進階的書《Effecitve Java》

內存泄漏與內存溢出

實例1

在這裏插入圖片描述
實例2
在這裏插入圖片描述

Java之路要走的高走得遠而JVM是無法繞過的門檻。

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