400-650-7353
您所在的位置:首頁(yè) > IT干貨資料 > java > 【Java基礎(chǔ)知識(shí)】什么是JVM?JVM內(nèi)存模型由什么組成?(上)

【Java基礎(chǔ)知識(shí)】什么是JVM?JVM內(nèi)存模型由什么組成?(上)

  • 發(fā)布: java培訓(xùn)
  • 來(lái)源:
  • 2022-12-08 16:28:12
  • 閱讀()
  • 分享
  • 手機(jī)端入口

本篇介紹JVM虛擬機(jī)中運(yùn)行時(shí)數(shù)據(jù)區(qū)的五個(gè)內(nèi)存區(qū)域:堆、方法區(qū)、虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器。這些地方也是我們平時(shí)開發(fā)中最常接觸到的地方,所以對(duì)其有所掌握了解還是很有必要的,也有助于JVM問(wèn)題排查。

JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,JVM是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),有著自己完善的硬件架構(gòu),如處理器、堆棧等。

為什么需要JVM?

Java語(yǔ)言使用Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼( 字節(jié)碼 ),就可以在多種平臺(tái)上不加修改地運(yùn)行。

Java文件必須先通過(guò)一個(gè)叫javac的編譯器,將代碼編譯成class文件,然后通過(guò)JVM把class文件解釋成各個(gè)平臺(tái)可以識(shí)別的機(jī)器碼,最終實(shí)現(xiàn)跨平臺(tái)運(yùn)行代碼。

JVM內(nèi)存模型

JVM內(nèi)存模型可以分為兩個(gè)部分,如下圖所示,堆和方法區(qū)是所有線程共有的,而虛擬機(jī)棧,本地方法棧和程序計(jì)數(shù)器則是線程私有的。

在JVM1.8中,圖中的 方法區(qū)為元數(shù)據(jù)區(qū) ,下面展開談一談這五個(gè)區(qū)域的作用。

堆(Heap):

在 Java 中,堆被劃分成兩個(gè)不同的區(qū)域:新生代 ( Young )、老年代 ( Old ),新生代 ( Young ) 又被劃分為三個(gè)區(qū)域:Eden、From Survivor、To Survivor。

下圖中的Perm代表的是永久代,但是注意永久代并不屬于堆內(nèi)存中的一部分,同時(shí)jdk1.8之后永久代也將被移除。

堆是java虛擬機(jī)所管理的內(nèi)存中最大的一塊內(nèi)存區(qū)域,也是被各個(gè)線程共享的內(nèi)存區(qū)域,該內(nèi)存區(qū)域存放了對(duì)象實(shí)例及數(shù)組(但不是所有的對(duì)象實(shí)例都在堆中)。

其大小通過(guò)-Xms(最小值)和-Xmx(最大值)參數(shù)設(shè)置(最大最小值都要小于1G),前者為啟動(dòng)時(shí)申請(qǐng)的最小內(nèi)存,默認(rèn)為操作系統(tǒng)物理內(nèi)存的1/64,后者為JVM可申請(qǐng)的最大內(nèi)存,默認(rèn)為物理內(nèi)存的1/4,默認(rèn)當(dāng)空余堆內(nèi)存小于40%時(shí),JVM會(huì)增大堆內(nèi)存到-Xmx指定的大小,可通過(guò)-XX:MinHeapFreeRation=來(lái)指定這個(gè)比列。

當(dāng)空余堆內(nèi)存大于70%時(shí),JVM會(huì)減小堆內(nèi)存的大小到-Xms指定的大小,可通過(guò)XX:MaxHeapFreeRation=來(lái)指定這個(gè)比列,當(dāng)然為了避免在運(yùn)行時(shí)頻繁調(diào)整Heap的大小,通常-Xms與-Xmx的值設(shè)成一樣。堆內(nèi)存 = 新生代+老生代+持久代。

在我們垃圾回收的時(shí)候,我們往往將堆內(nèi)存分成新生代和老生代(大小比例1:2),新生代中由Eden和Survivor0,Survivor1組成,三者的比例是8:1:1,新生代的回收機(jī)制采用復(fù)制算法,在Minor GC的時(shí)候,我們都留一個(gè)存活區(qū)用來(lái)存放存活的對(duì)象,真正進(jìn)行的區(qū)域是Eden+其中一個(gè)存活區(qū),當(dāng)我們的對(duì)象時(shí)長(zhǎng)超過(guò)一定年齡時(shí)(默認(rèn)15,可以通過(guò)參數(shù)設(shè)置),將會(huì)把對(duì)象放入老生代,當(dāng)然大的對(duì)象會(huì)直接進(jìn)入老生代,老生代采用的回收算法是標(biāo)記整理算法。

方法區(qū)(Method Area)

其實(shí)方法區(qū)是在JDK1.8以前的版本里存在的一塊內(nèi)存區(qū)域,主要就是存放從class文件里加載進(jìn)來(lái)的類的,而且常量池也是在這塊區(qū)域內(nèi)的。

但是在JDK1.8之后,這塊區(qū)域搖身一變,換了名字,叫做“Metaspace”,翻譯過(guò)來(lái)就是“元數(shù)據(jù)空間”的意思,當(dāng)然它只是改了個(gè)名,實(shí)現(xiàn)的功能是沒(méi)變的。

方法區(qū)(Method Area)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類型信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼緩存等數(shù)據(jù)。

1.類型信息

對(duì)每個(gè)加載的類型(類class、接口interface、枚舉enum、注解annotation),JVM必須在方法區(qū)中存儲(chǔ)以下類型信息:

①這個(gè)類型的完整有效名稱(全名=包名.類名)

②這個(gè)類型直接父類的完整有效名(對(duì)于interface或是java.lang.0bject,都沒(méi)有父類)

③這個(gè)類型的修飾符(public, abstract,final的某個(gè)子集)

④這個(gè)類型直接接口的一個(gè)有序列表

2.域信息(Field)成員變量

JVM必須在方法區(qū)中保存類型的所有域的相關(guān)信息以及域的聲明順序。

域的相關(guān)信息包括:域名稱、域類型、域修飾符(public, private,protected,static,final, volatile, transient的某個(gè)子集)

3.方法(Method)信息

JVM必須保存所有方法的以下信息,同域信息一樣包括聲明順序:

方法名稱

方法的返回類型(或void)·方法參數(shù)的數(shù)量和類型(按順序)

方法的修飾符(public, private,protected,static, final,synchronized,native,abstract的一個(gè)子集)

方法的字節(jié)碼(bytecodes)、操作數(shù)棧、局部變量表及大小(abstract和native方法除外)

文章“【Java基礎(chǔ)知識(shí)】什么是JVM?JVM內(nèi)存模型由什么組成?(上)”已幫助

更多內(nèi)容

>>本文地址:http://liujunjsxg.cn/zhuanye/2022/72418.html

THE END  

聲明:本站稿件版權(quán)均屬中公教育優(yōu)就業(yè)所有,未經(jīng)許可不得擅自轉(zhuǎn)載。

1 您的年齡

2 您的學(xué)歷

3 您更想做哪個(gè)方向的工作?

獲取測(cè)試結(jié)果
  • 大前端大前端
  • 大數(shù)據(jù)大數(shù)據(jù)
  • 互聯(lián)網(wǎng)營(yíng)銷互聯(lián)網(wǎng)營(yíng)銷
  • JavaJava
  • Linux云計(jì)算Linux
  • Python+人工智能Python
  • 嵌入式物聯(lián)網(wǎng)嵌入式
  • 全域電商運(yùn)營(yíng)全域電商運(yùn)營(yíng)
  • 軟件測(cè)試軟件測(cè)試
  • 室內(nèi)設(shè)計(jì)室內(nèi)設(shè)計(jì)
  • 平面設(shè)計(jì)平面設(shè)計(jì)
  • 電商設(shè)計(jì)電商設(shè)計(jì)
  • 網(wǎng)頁(yè)設(shè)計(jì)網(wǎng)頁(yè)設(shè)計(jì)
  • 全鏈路UI/UE設(shè)計(jì)UI設(shè)計(jì)
  • VR/AR游戲開發(fā)VR/AR
  • 網(wǎng)絡(luò)安全網(wǎng)絡(luò)安全
  • 新媒體與短視頻運(yùn)營(yíng)新媒體
  • 直播帶貨直播帶貨
  • 智能機(jī)器人軟件開發(fā)智能機(jī)器人
 

快速通道fast track

近期開班時(shí)間TIME