JAVA 垃圾回收機制GC

JVM的堆是Java對象的活動空間,程序中的類的對象從中分配空間,其存儲着正在運行着的應用程序用到的所有對象。

GC的工作目的:在堆中,找到已經無用的對象,並把這些對象佔用的空間收回使其可以重新利用.

JVM堆
(1) 新域:存儲所有新成生的對象
(2) 舊域:新域中的對象,經過了一定次數的GC循環後,被移入舊域
(3)永久域:存儲類和方法對象,從配置的角度看,這個域是獨立的,不包括在JVM堆內。默認爲4M。

新域會被分爲3個部分:
1.第一個部分叫Eden。
2.另兩個部分稱爲輔助生存空間(幼兒園),一個稱爲A空間(From sqace),一個稱爲B空間(To Space)。

對於新生成的對象,都放在Eden中;當Eden充滿時(小孩太多 了),GC將開始工作,首先停止應用程序的運行,開始收集垃圾,把所有可找到的對象都複製到A空間中,一旦當A空間充滿,GC就把在A空間中可找到的對象 都複製到B空間中(會覆蓋原有的存儲對象),當B空間滿的時間,GC就把在B空間中可找到的對象都複製到A空間中,AB在這個過程中互換角色,在活動對象經過一定次數的GC操作後,這些活動對象就會被放到舊域中。

對於舊域,採用的是tracing算法的一種,稱爲標記-清除-壓縮收 集器,注意,這有一個壓縮,這是個開銷挺大的操作。
垃圾回收主要是對Young Generation塊和Old Generation塊內存進行回收,YG用來放新產生的對象,經過幾次回收還沒回收掉的對象往OG中移動,
對YG進行垃圾回收又叫做MinorGC,對 OG垃圾回收又叫MajorGC,兩塊內存回收互不干涉。

經驗:
1.JVM堆的大小決定了GC的運行時間。如果JVM堆的大小超過一定的限度,那麼GC的運行時間會很長。
2.對象生存的時間越長,GC需要的回收時間也越長,影響了回收速度。
3.大多數對象都是短命的,所以,如果能讓這些對象的生存期在GC的一次運行週期內,wonderful!
4.應用程序中,建立與釋放對象的速度決定了垃圾收集的頻率。
5.如果GC一次運行週期超過3-5秒這會很影響應用程序的運行,應該減少JVM堆的大小了。
6.通常情況下,JVM堆的大小應爲物理內存的80%。

內存溢出
jvm內存溢出的幾種情況。

OutOfMemoryError:Java heap space
jvm的堆內存溢出,在jvm中98%的內存都在等待GC回收,且Heap Size不足2%的可用空間時,將拋出此錯誤,對應的解決辦法增加-xmx和-xms的大小。

OutOfMemoryError:PermGen Space
jvm的非堆內存溢出,可能情況有如下幾種

如果web app下用大量的第三方jar,其總大小超過非堆內存的最大值,會拋出此異常
項目擁有太多的class文件,恰好maxPermSize設置的小於class總大小,會拋出此異常
tomcat部署的時候,不會清理前面加載的環境,只會將context更改爲新部署的代碼,所以非堆內存越來越多
OutOfMemoryError:unable to new native thread:
這是jvm無法創建新線程,這個錯誤比較少見,也比較奇怪。主要是jvm與內存的比例有關。這種怪事因爲jvm已經被系統分配了大量的內存。並且它至少佔用可用內存的一半空間。可以嘗試重啓tomcat或加大非堆內存對應的值。

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