Java虛擬機JVM底層原理分析

jdk體系結構

jvm虛擬機


紫色區域是線程獨享
橘色區域是所有線程共享

棧幀

虛擬機棧(線程棧):存放局部變量。
例如:下圖中a、b、c、math、

每個線程在運行前,java虛擬機都會爲其分配一塊自己獨立的棧內存空間。存放局部變量。

棧幀是棧中更細緻的內部結構,線程中每個方法分配一個棧幀(專屬獨立)。如下圖

局部變量表、操作數棧

當方法執行完畢後釋放棧幀內存區域。
先進後出,先執行main()方法在,再執行compute()方法。然後銷燬compute(),再進入main()

方法出口

程序計數器


每個線程分配一個程序計數器 ,記錄當先線程執行代碼的行號。字節碼執行引擎動態修改它

方法區

jdk1.8 以後叫做 元空間
實際上是直接放內存裏的。
嚴格意義不算jvm中的

方法區裏面存放
常量
靜態變量
類信息(字節相關的類信息)


本地方法棧(現在基本不用)

private native void start0()
java與c交互,就是使用本地方法
執行到這行代碼 時,會由底層的執行引擎去分析這個本地方法,去調用c語言的庫函數(Windows 中的.dll文件)。
這裏面的實現使用c語言實現的。


new出來的對象最先放在eden區的。
eden區的大小是固定的。 當eden區放滿時,jvm會進行==minor gc(young gc)==執行引擎會開啓一個垃圾收集線程,來收集eden區的垃圾對象。
那什麼叫垃圾對象的,可用如下算法

可達性分析算法(如圖)

所有在gc route鏈條上的對象都是非垃圾對象。把非垃圾對象直接複製(複製算法)到survivor區的一塊空的區去。eden區剩餘對象即垃圾對象(沒有gc router指向的對象)直接清理掉。
沒有被處理的對象的分代年齡會加一

一個對象包含對象頭,裏面有一個分代年齡(gc的次數)
等待eden區再次滿了,再次觸發minor gc,會回收 eden區和survivor區中from區的對象,gc router鏈條上的對象會直接複製到survivor區的to區中,eden區和survivor區中from區的垃圾對象直接銷燬。

等待eden區再次滿了,再次觸發minor gc,會回收 eden區和survivor區中to區的對象,gc router鏈條上的對象會直接複製到survivor區的from區中,eden區和survivor區中to區的垃圾對象直接銷燬。

以此類推…

當分代年齡達到15(gc15次還被引用),這種對象會被放到老年代。

當老年代放滿了會觸發full gc
full gc會回收整個堆
如果沒辦法回收 就會發生OOM(內存溢出)

web應用中可能會被移動到老年代的對象
線程池、靜態變量引用的對象、spring容器中的been、service、controller、代碼初始化的緩存對象

STW(stop the world)
執行引擎開啓 gc 線程時候STW(停掉用戶線程),專心收集垃圾。

jvm調優的目的:減少STW的時間(減少full gc 次數,和一次full gc的時間)

jvm調優實戰





面試題:能否對jvm調優,讓其幾乎不發生full gc

解答

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