日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java虚拟机:JVM 主要组成部分与内存区域

發布時間:2024/9/30 java 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java虚拟机:JVM 主要组成部分与内存区域 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、JVM 主要組成部分:

?JVM包含兩個子系統和兩個組件,分別為:

  • Class loader(類裝載子系統):根據給定的全限定名類名來裝載class文件到運行時數據區的方法區中
  • Execution engine(執行引擎子系統):執行引擎也叫解釋器,負責解釋class的指令,在提交給操作系統執行
  • Runtime data area(運行時數據區組件):即我們常說的JVM的內存
  • Native Interface(本地接口組件):與native lib交互,它的作用是融合不同的編程語言為Java所用,是其它編程語言交互的接口

????????首先通過編譯器把 Java源代碼轉換成字節碼,Class loader(類裝載)再把字節碼加載到內存中,將其放在運行時數據區的方法區內,而字節碼文件只是 JVM 的一套指令集規范,并不能直接交給底層操作系統去執行,因此需要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程中需要調用其他語言的本地庫接口(Native Interface)來實現整個程序的功能。

二、JVM 內存區域:

JVM 在執行 Java 程序時,會將內存劃分為若干個不同的數據區域,不同的區域用途不同,創建和銷毀時間也不相同。在 JDK1.8 版本之后對運行時數據區域做了些修改,下面我們分別來看看修改前后的內存區域是怎么樣的。

1、JDK1.8之前的JVM內存區域如下圖:

2、JDK8之后的JVM內存區域如下圖:

3、各區域的的作用:

(1)程序計數器:

當前線程執行的字節碼的行號指示器,記錄當前線程執行到程序的哪個位置,通過改變計數器的值,可以選取下一條需要執行的字節碼指令。該區域是線程私有,是唯一一個不會發生OOM的區域。

(2)Java虛擬機棧:

描述 Java 方法執行的內存模型,每個方法執行時都會創建一個棧幀,用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每個方法從調用到執行完成,就對應著一個棧幀在虛擬機中入棧到出棧的過程。該區域線程私有,生命周期與線程的生命周期相同。

(3)本地方法棧:

本地方法棧的作用和虛擬機棧的作用非常相似,區別是本地方法棧則為Native方法服務,而虛擬機棧為執行java方法服務,該區域也是線程私有。

(4)Java堆:

用于存儲對象實例,是占用內存最大的區域,可劃分為新生代和老年代,新生代又可細分為?Eden區、From Survivor區、To Survivor區。

在 HotSpot 中,對象在堆內存布局分成三部分:對象頭,實例數據,對齊填充。

① 對象頭:包括兩部分的信息:

  • 運行時數據:用于存儲對象自身的運行時數據,如哈希碼,GC代年齡,鎖狀態標志、線程持有的鎖、偏向線程ID等。
  • 類型指針:即對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。如果對象是一個Java數組,那對象頭中還必須有一塊用于記錄數組長度的數據。

② 實例數據:是對象真正存儲的有效信息,是在程序代碼中所定義的各種類型的字段內容,相同寬度的字段會被分配到一起。

③ 對齊填充:并不是必然存在的,僅起著占位符的作用。

(5)方法區:

????????用于存儲類信息,包括運行時常量池、靜態變量、常量、即時編譯后的代碼(即class文件)等數據。與Java堆一樣不需要連續的內存,并且可以動態擴展,動態擴展失敗會拋出 OOM 異常,該區域被所有線程共享。對這塊區域進行垃圾回收的主要目標是對常量池的回收和對類型的卸載,但是一般比較難實現。

? ? ? ? 方法區是一個 JVM 規范,永久代與元空間都是其一種實現方式。JDK8 之前,Hotspot 中方法區的實現是永久代(Perm),JDK8 開始使用元空間(Metaspace),以前永久代的靜態變量和常量池移至堆內存,其他內容移至元空間,元空間直接在本地內存分配。那為什么要使用元空間取代永久代的實現?主要是為了方便管理方法區:

① 永久代的方法區,和堆使用的物理內存是連續的。對于永久代,由于類及方法的信息等比較難確定其大小,所以指定永久代的大小比較困難,太小容易出現永久代溢出,太大則容易導致老年代溢出,并且每次?Full GC 之后永久代的大小都會改變,如果動態生成很多 class 的話,就很可能出現 OOM,畢竟永久代的空間配置有限。

②?JDK8之后,方法區存在于元空間,物理內存不再與堆連續,而是直接存在于本地內存中,理論上機器內存有多大,元空間就有多大。

③ 字符串存在永久代中,容易出現性能問題和內存溢出。

④ 永久代會為 GC 帶來不必要的復雜度,并且回收效率偏低

參考文章:Java內存區域(運行時數據區域)和內存模型(JMM) - czwbig - 博客園

總結

以上是生活随笔為你收集整理的Java虚拟机:JVM 主要组成部分与内存区域的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。