3.2019年周陽老師JVM·第三部分

Heap堆結構簡介

堆包括三部分:新生代,老年代,元空間/永久代。
新生代包括:伊甸園區,倖存者0區,倖存者1區。
在這裏插入圖片描述
在這裏插入圖片描述
7是永久代,8是元空間。
物理上有2部分:新生+養老。

heap堆new對象流程

知識點:new一個對象,是new在了伊甸園區。
在這裏插入圖片描述
伊甸園區發生的GC是YGC。y是young的意思。也是輕量級的GC。YGC之後倖存的對象,放到倖存者0區,別名from區。
如果15次GC都沒被清空,就會送到養老區。養老區滿了,開啓Full GC(FGC),Full gc 多次執行完畢之後,還不能清理出空間,就OOM了。

Transfervalue

基本類型傳複印件,引用類型傳引用,string特殊,方法內部會新建一個指向,並不改變原來的指向。
在這裏插入圖片描述
這個題需要注意:棧裏面壓入一個一個的方法(棧幀),每一個棧幀裏面有不同的局部變量,age就是局部變量。雖然傳給了另一個方法,是另一個棧幀的入參,是另外一個部分的局部變量,在那個棧幀中改變age,不影響main這個棧幀中age的值。

new person,引用在棧,數據在堆中,傳給方法的是內存地址,指向關係如下圖:

在這裏插入圖片描述
元空間裏有常量池,string的使用原則是池子裏有我就複用,沒有我就在常量池裏面新建。string傳過去的確實是引用,但是他新建的邏輯是沒有就新建,而不是在原來位置修改,就導致了,main中的string指向的內容沒有改變。
在這裏插入圖片描述

對象生命週期和GC

倖存者0區,簡稱s0,別名叫from區,倖存者1區,簡稱s1,別名叫to區。
在這裏插入圖片描述
在這裏插入圖片描述
重點:注意關注堆中各部分的比例。新生代:老年代 = 1:2 ,Eden:From:to = 8:1:1.
輕GC(ygc,minorGC)的過程:複製,清空,互換。

永久代

在這裏插入圖片描述
永久代是7的叫法,元空間是8的叫法。
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
永久代幾乎沒有垃圾回收。

堆參數調優

在這裏插入圖片描述
在這裏插入圖片描述
這張圖代表的是各個區發生的GC類型,以及調整時的參數設置。
邏輯上JVM分爲三塊,物理上分爲2塊。
理解每個參數的意思:

  • Xms:s是start的意思,初始化大小
  • Xmx:x是max的意思,最大化大小
  • Xmn:n是new的意思,代表新生代三塊組合起來的大小
    新生區跟養老區是默認1:2的關係。
  • XX:PermSize,永久代的初始值
  • XX:MaxPermSize,永久代的最大值
    跟永久代有關的是jdk7的用法,以後用不到了,jdk8以後就改名了。
    在這裏插入圖片描述
    jdk8只是更新了一個元空間,替代了持久區,其他是一樣的。
    因爲這些參數設置的問題,你的內存條可能不會被全部使用,也就是說,單純差個內存條,不會讓程序性能有想象中的提升,需要調整jvm參數去適配。默認java出廠只用物理內存的四分之一,加個4G內存條,只用1G。
    在這裏插入圖片描述
    在這裏插入圖片描述
    查看CPU核數:
    在這裏插入圖片描述
    Runtime這個類就是對JVM體系結構中運行時數據區的抽象。
    在這裏插入圖片描述
    在這裏插入圖片描述
    代碼測試:Xms(64分之一內存條),Xmx(四分之一內存條)的設置的值。
    在這裏插入圖片描述
    運行結果:
    在這裏插入圖片描述
    最佳實踐:生產環境,Xms和Xmx的大小必須一樣!!!!是爲了避免jvm和應用程序爭搶內存,避免內存忽高忽低,產生停頓
    idea如何配置jvm?
    在這裏插入圖片描述
    上圖是演示變更JVM的堆內存的初始值和最大值,然後打印gc的日誌。
    配置之後再次運行上面的4行代碼,結果如下:
    在這裏插入圖片描述
    分析上圖,實現了初始和最大堆空間一致的效果。根據GC日誌,可以證明,堆由young區,old區,metaspace區組成。這是邏輯組成的證明。也可以證明物理組成,因爲young區的total|+old區的total就等於我們配置的Xmx和Xms。如此就證明了物理上由young+old組成。如下圖:
    在這裏插入圖片描述

如何幹爆堆,測試方式i如下,思路爲調整堆大小,然後死循環創建對象。
在這裏插入圖片描述
在這裏插入圖片描述
運行實際結果截圖:堆空間溢出
在這裏插入圖片描述
5個常見的異常,這個需要回答。
一句話撐爆:
在這裏插入圖片描述
回到循環創建的代碼,分析打印的日誌:
在這裏插入圖片描述
可以分析出先young-gc,很多次ygc之後是一次full-gc,然後又是多次young gc。直到一瞬間,full gc之後也沒用空間了,jvm就撂挑子了,如下圖:
在這裏插入圖片描述
最初的gc過程有這個過程的理論描述(下圖),上圖是實際的執行過程。發生堆內存的oom異常,最近一次gc是full gc。
在這裏插入圖片描述

GC收集日誌信息

GC的執行過程一定是先輕後重,先輕gc(young gc,minor gc)再重GC(major gc)。
在這裏插入圖片描述

分析一下gc的日誌:
第一行,因爲分配空間失敗了,產生young gc。也就是內存不夠用才gc。
第二行:gc發生在young區域,2048是gc之前的用的空間,488是gc之後用的空間,2560是young區(新生代)的總內存(總共大小)。young gc前jvm堆內存佔用2048k,之後是773k,9728k是配置的jvm堆總大小。 整個ygc耗時0.0015243 秒。
第三行:時間,用戶耗時,系統耗時,時間耗時。

在這裏插入圖片描述

分析一下爆炸之前的最後一個full-gc:
在這裏插入圖片描述
full gc的結果只有2個,要麼成功,要麼就oom。
young區總計2048k,gc前後都是0,old區gc前後只改變了很少的一點,元空間也是,幾乎沒有清理出太多空間。
清理不出來空間,時間就是0,這種情況,就崩了,會導致oom。
在這裏插入圖片描述
在這裏插入圖片描述

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