程序啟動后由類裝載系統(tǒng)將我們的.clss字節(jié)碼文件加載到內存區(qū)域,然后通過執(zhí)行引擎去運行整個字節(jié)碼文件!

下面主要說說內存模型,它" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網站運營 > 簡單整理java虛擬機

簡單整理java虛擬機

時間:2023-07-15 04:06:01 | 來源:網站運營

時間:2023-07-15 04:06:01 來源:網站運營

簡單整理java虛擬機:java虛擬機組成部分:類裝載子系統(tǒng)、字節(jié)碼執(zhí)行引擎、內存模型

程序啟動后由類裝載系統(tǒng)將我們的.clss字節(jié)碼文件加載到內存區(qū)域,然后通過執(zhí)行引擎去運行整個字節(jié)碼文件!

下面主要說說內存模型,它由堆、棧、本地方法棧、方法區(qū)、程序計數器組成

其中棧也叫虛擬棧,線程棧(方法執(zhí)行順序first in afer out 先進后出)

比如上面整個main方法在運行時候,會開啟主線程,java虛擬機就會對線程里面對局部變量做內存分配,讓其存儲!如果是多線程,那么每個線程有自己獨立對棧內存空間,讓其存儲對應局部變量!

而棧內存區(qū)域中還劃分了其他內存區(qū)域包括棧幀(主要放main方法、count方法等不同方法等內存區(qū)域)也就是說java內存中一個方法對應一塊棧幀!總結一句,棧首先是虛擬機一塊內存,也是一種數據結構,它里面用數據結構棧組織我們的內存數據!其中主要組成部分包括:局部變量表、操作數棧、動態(tài)鏈接、方法出口等

現在對上面程序Math.class執(zhí)行javap -c Math.class反編譯得到jvm指令碼,去查詢手冊看到每行代碼執(zhí)行的方法;

舉個例子:比如iconst_1

操作數棧中執(zhí)行算法操作,可以理解成程序在運行時,一個臨時的中轉內存區(qū)域,也是用的先進后出棧的數據結構!




方法出口是執(zhí)程序行完方法后,馬上返回主方法的位置,即count方法執(zhí)行完后返回到main 方法到位置,main方法即將執(zhí)行到程序計數器到數值!

程序計數器就是正準備執(zhí)行指令碼的位置(行號,可以理解成指針)

math是new出來的局部變量,放在棧里的,但是對應的值放在堆里的,兩者關系:棧中的math局部變量存的是堆中math值的地址,是一個引用!

棧中有很多對象這種局部變量由指針指向堆中的很多對象!




方法區(qū)(jdk8以后叫元空間,以前叫持久代),主要由類裝載子系統(tǒng)加載字節(jié)碼文件加載到位置就是我們到方法區(qū)!主要放到是一系列到類元信息(常量、靜態(tài)變量、類元信息),類元信息是類的組成部分,類也有一個類對象,通過反射,把類的方法,常量組成到部分;

math和math1都是math對象,對象組成部分有個對象頭,存儲了很多對象信息,在new math對象時候,會在對象頭放Math類到地址指針,因為在運行到時候,就是通過整個指針找對應類到指令碼;

我需要找到指令碼,需要知道是那個類,在new 的時候會存一個地址指針

動態(tài)鏈接:程序運行時,放的是方法對應對類元信息的位置,動態(tài)生成的,只有程序在運行的時候

#4由兩部分組成,Math類和compute:()方法,在jvm中統(tǒng)稱符號;程序執(zhí)行時候,會把這些靜態(tài)符號擁有的地址指針符號存到動態(tài)鏈接內存中,說白堆和方法區(qū)也有一個聯(lián)系,有很多指針,堆中很多對象中對象頭有一個類型指針指向對象所屬類的類元信息的相關的地址!

方法區(qū)嚴格意義上不算java虛擬機內部的內存,它用的操作系統(tǒng)的直接內存;比如:操作系統(tǒng)16G大小,分配java虛擬機內存1G,方法區(qū)用的內存是從剩下的15G中拿的!規(guī)范上來講,算內存模型的一塊組成部分!

本地方法棧要從本地方法說起,底層有很多native方法,就是我們java的本地方法,底層并不是java語言實現的,是C語言實現的!在程序執(zhí)行到此類方法會調用C語言對此方法對實現,類似jar包,現在技術發(fā)展,已經用很少了!它需要的內存就就在本地方法,也是線程獨享的,

堆,調優(yōu)主要就是對堆進行調優(yōu)!

假設總共有600M內存空間,按照年輕代:老年代比例=1:2,我們?yōu)槟贻p代分配200M內存空間,老年代400M內存空間,那么eden區(qū)大概占140M,From和To區(qū)分別占40M;

new出來對象先放在eden區(qū),如果放滿了,會做出兩種事情:

第一種:

java虛擬機則會執(zhí)行一次gc(Garbage Collection,垃圾回收),這里是minor gc,會對處理掉無效對對象,當main方法執(zhí)行完,java進程退出前,棧里已經清空了,但堆里math仍然在,就是沒有指針指向了,gc就會處理掉這里math對象;

GC Roors根節(jié)點:類加載器、Thread、虛擬站棧當本地變量表,statis成員、常量引用、本地方法棧當變量等

比如:java虛擬機棧等本地變量表也是一種GC Roots根,消亡的時候,沒有指針指向堆中的對象,這些對象就成了游離狀態(tài),java虛擬機就會回收這些變量;

第二種:

將存活對象挪到Survivor區(qū)的from區(qū),如果from區(qū)放滿了,也會出發(fā)GC,將存活對象挪到To區(qū),涉及到了一系列到算法包括:垃圾收集算法,標記清除算法,復制算法等,如果To區(qū)滿了,也會執(zhí)行GC,

每個對象都存在一個分代年齡,存在對象頭里,如果它在Survivor區(qū)經歷過一次minor gc,分代年齡會+1,將對象挪回到From區(qū),不斷交替循環(huán),隨著分代年齡到15,再執(zhí)行一次minor gc 就會挪到老年代,

固定的線程池經過一系列的輪轉,就會在老年代!老年代一旦被放滿,java虛擬機就會執(zhí)行一次full gc!

如下面程序會生成大量HeapTest對象,但是又不能被回收,因為被heapTests引用了!

打開jvisualvm工具

gc日志:如下圖

java虛擬機調優(yōu)的目的就是:減少full gc的次數和full gc(會卡死)一次執(zhí)行的時間!

上面說的就是元空間滿了,導致full gc,元空間參數默認21M,現在調大點即可,一個web應用啟動過程中,耗時太久,war包或者jar包太大,在啟動的時候,看下日志中的full gc!

如何打印gc日志呢?































關鍵詞:虛擬,整理,簡單

74
73
25
news

版權所有? 億企邦 1997-2025 保留一切法律許可權利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關閉