JVM調優由淺到深(三)——垃圾回收

垃圾回收的區域

一般發生垃圾回收是在java堆中,所以我們重點講java堆

java堆

java堆可以說是Java運行時內存中最爲重要的部分,幾乎所有的對象和數組都是在堆中分配空間的。
Java堆分爲新生代和老年代兩個部分,
新生代用於存放剛剛產生的對象和年輕的對象,如果對象一直沒有被回收,生存得足夠長,就會被移入老年代。

垃圾回收把對象劃分爲幾個部分

垃圾回收把對象劃分爲了新生代,年老代,永久代(元空間)。

新生代

新生代又可進一步細分爲
eden、
survivor space0(s0 或者 from space)
survivor space1(s1或者to space)。

eden:對象的出生地,大部分對象剛剛建立時,通常會存放在這裏。
s0 和 s1 爲 survivor(倖存者)空間,存放其中的對象至少經歷過一次垃圾回收,並得以倖存。如果在倖存區的對象到了指定年齡仍未被回收,則有機會進入老年代(tenured)。

在這裏插入圖片描述

年老代

年老代存放從年輕代存活的對象。一般來說年老代存放的都是生命期較長的對象。

永久代

用於存放靜態文件,如今Java類、方法等。持久代對垃圾回收沒有顯著影響,但是有些應用可能動態生成或者調用一些class。

元空間

JDK8 HotSpot JVM 將移除永久區,使用本地內存來存儲類元數據信息並稱之爲:元空間(Metaspace)。

元空間的本質和永久代類似,都是對JVM規範中方法區的實現。不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機中,而是使用本地內存。因此,默認情況下,元空間的大小僅受本地內存限制。

元空間理論上取決於32位/64位系統可虛擬的內存大小。不過,可以通過設置參數 MaxMetaspaceSize 限制本地內存分配給類元數據的大小。如果沒有指定這個參數,元空間會在運行時根據需要動態調整。

講到這裏我們應該再說下方法區。
方法區是運行時數據區的一部分,方法區是JVM的一種規範,永久區是一種具體實現,元空間也是一種具體的實現。

在JDK8之前的Host Spot虛擬機的實現中,方法區也被稱爲永久區,是一塊獨立於 Java 堆的內存空間。
雖然叫永久區,但是永久區中的對象同樣可以被 GC 回收的。對永久區 GC 的回收,通常主要從兩個方面分析:一是 GC 對永久區常量池的回收;二是永久區對類元數據的回收。永久區的垃圾回收是和老年代(old generation)捆綁在一起的,因此無論誰滿了,都會觸發永久代和老年代的垃圾收集。

在 Java8 中,永久區已經被 Metaspace 元空間取而代之。
原永久區的數據被分到了堆和元空間中:
元空間存儲類的元信息,靜態變量和常量池等放入堆中。
相應的,JVM參數 PermSize 和 MaxPermSize 被 MetaSpaceSize 和 MaxMetaSpaceSize 取代。

元空間的配置詳細說明如下:

  -XX:MetaspaceSize:
  初始空間大小,達到該值就會觸發垃圾收集進行類型卸載,
  同時GC會對該值進行調整:如果釋放了大量的空間,就適當降低該值;
  如果釋放了很少的空間,那麼在不超過MaxMetaspaceSize時,適當提高該值。
  
  -XX:MaxMetaspaceSize:
  最大空間,默認是沒有限制的。

 除了上面兩個指定大小的選項以外,還有兩個與 GC 相關的屬性:
  -XX:MinMetaspaceFreeRatio:
  在GC之後,最小的Metaspace剩餘空間容量的百分比,減少爲分配空間所導致的垃圾收集
  
  -XX:MaxMetaspaceFreeRatio:
  在GC之後,最大的Metaspace剩餘空間容量的百分比,減少爲釋放空間所導致的垃圾收集

爲什麼1.8要移除永久區,改爲元空間??

  • 字符串存在永久代中,現實使用中易出問題, 由於永久代內存經常不夠用或發生內存泄露,爆出異常 java.lang.OutOfMemoryError: PermGen

  • 類及方法的信息等比較難確定其大小,因此對於永久代的大小指定比較困難,太小容易出現永久代溢出,太大則容易導致老年代溢出。

  • 永久代會爲 GC 帶來不必要的複雜度,並且回收效率偏低。

什麼時候會出現 java.lang.OutOfMemoryError: Metaspace,這種內存溢出的問題?
因爲大量調用接口,而接口又用到了反射類加載器ClassLoader。
而且Metaspace中類的元數據信息只有在加載它的ClassLoader被釋放後纔會發生寫在,如果ClassLoader對象一直存活,那麼它所加載的類的元數據信息將不會被卸載。

可以參考以下博客

https://www.jianshu.com/p/1a0b4bf8d498
https://blog.csdn.net/a15939557197/article/details/90635460

GC圖

在這裏插入圖片描述

gc類型分爲:minor gcmajor gc ,major的速度比minor慢10倍至少

發生在 young(主要是Survivor)區的gc稱爲 minor gc
發生在 old(Tenured)區的gc稱爲 major gc
發生在新生代和老年代的gc稱爲 full gc

會發生的異常

一般垃圾回收會發生兩個異常
1)OutOfMemoryError
2)StackOutflowError

如圖

圖片來自網絡
在這裏插入圖片描述

發佈了32 篇原創文章 · 獲贊 14 · 訪問量 4489
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章