JVM运行时数据区分析
#1.概述
整個JVM構成??,由三部分組成:類加載器機制、運?時數據區、執?引擎。#2.JVM運行時數據區的規范
我們來聊聊這個規范怎么理解,目前運行數據區共分為了方法區、堆、虛擬機棧、本地方法棧、程序計數器共5大模塊。
就拿方法區來說,、?法區是Java虛擬機規范中的定義,是?種規范,?永久代和元空間是 HotSpot 虛擬機不同版本的兩種實現。下面我們會詳細說明為什么。
#2.1.JVM運?時數據按照線程使?情況和職責分成兩?類
#2.1.1.線程獨享
不需要垃圾回收 職責:程序執?區域 虛擬機棧、本地?法棧、程序計數器#2.1.2.線程共享
垃圾回收、存儲類的靜態數據和對象數據 職責:數據存儲區域 堆和?法區概括地說來,JVM初始運行的時候都會分配好Method Area(方法區)和Heap(堆),而JVM 每遇到一個線程,就為其分配一個Program Counter Register(程序計數器),?VM Stack(虛擬機棧)和Native Method Stack?(本地方法棧),當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所占用的內存空間也會被釋放掉。這也是為什么我把內存區域分為線程共享和非線程共享的原因,非線程共享的那三個區域的生命周期與所屬線程相同,而線程共享的區域與JAVA程序運行的生命周期相同,所以這也是系統垃圾回收的場所只發生在線程共享的區域(實際上對大部分虛擬機來說知發生在Heap上)的原因。
#2.2.JVM的運?時數據區的使?順序
線程共享的兩塊運?時數據區,是在JVM啟動的時候,就已經按照參數設置進?內存分配了。另外也就是說,線程獨享的三塊運?時數據區,不是隨著JVM啟動?分配內存的。這里要注意一下,這里說的運行時數據區就是指方法區和堆兩塊。在整個運行時數據區虛擬機棧和本地方法棧、程序計數器這三塊沒有數據的存儲的嗎?
#2.3.JVM啟動的時候,干了什么東西?
#2.4.程序執行的時候,JVM又干了什么東西?
#3.Hotspot運?時數據區
jdk1.7之前,HotSpot虛擬機對于?法區的實現稱之為“永久代”, Permanent Generation 。 jdk1.8之后,HotSpot虛擬機對于?法區的實現稱之為“元空間”, Meta Space 。 ?法區是Java虛擬機規范中的定義,是?種規范,?永久代和元空間是 HotSpot 虛擬機不同版本的兩種實現。#3.1.不同 JDK版本方法區和堆存儲數據的變化
首先在真實機器上JVM運行時,JVM里的堆和方法區都是需要占據真實機器的內存的。因此上面那個圖可以理解最外面那層代表就是機器內存。
參考:JVM與Linux的內存關系詳解:JVM 與 Linux 的內存關系詳解 - 知乎
1.6版本的時候,方法區中永久代存儲的數據有類信息、運行時常量池、靜態變量、JIT編譯之后的代碼。
在1.7版本,oracle開始去永久代計劃,在這個版本中,方法區中永久代就只保留了類的信息、JIT編譯之后的代碼、OOM。相比1.6版本,1.7版本吧運行時常量池(字符串常量池)放到了堆中來管理。
在1.8版本之后,真正的去除了永久代,方法區的具體實現變成了“元空間”,元空間保存了類信息、JIT編譯之后的代碼。
#3.2.分配JVM內存空間
#3.2.1分配堆的大小
–Xms(堆的初始容量) -Xmx(堆的最?容量) # 如果為了提?性能,可以考慮去浪費空間,就是將初始容量和最?容量相等#3.2.2.分配方法區的大小
-XX:PermSize永久代的初始容量 -XX:MaxPermSize永久代的最?容量 -XX:MetaspaceSize元空間的初始??,達到該值就會觸發垃圾收集進?類型卸載,同時GC會對該值進?調整:如果釋放了?量的空間,就適當降低該值;如果釋放了很少的空間,那么在不超過MaxMetaspaceSize時,適當提?該值。-XX:MaxMetaspaceSize最?空間,默認是沒有限制的。 除了上?兩個指定??的選項以外,還有兩個與 GC 相關的屬性: -XX:MinMetaspaceFreeRatio在GC之后,最?的Metaspace剩余空間容量的百分?,減少為分配空間所導致的垃圾收集 -XX:MaxMetaspaceFreeRatio在GC之后,最?的Metaspace剩余空間容量的百分?,減少為釋放空間所導致的垃圾收集#3.2.3.分配線程空間的??
-Xss:為jvm啟動的每個線程分配的內存??,默認JDK1.4中是256K,JDK1.5+中是1M#4.方法區
#4.1.?法區存儲內容
類型信息,?如Class ?法信息,?如Method(?法名稱、?法參數列表、?法返回值信息) 字段信息,?如Field(字段類型,字段名稱需要特殊設置才能保存的住) Code區,存儲的是?法執?對應的字節碼指令 ?法表(?法調?的時候) 在A類的main?法中去調?B類的method1?法,是根據B類的?法表去查找合適的?法,進?調?的。 靜態變量(類變量)---JDK1.7之后,轉移到堆中存儲 運?時常量池(字符串常量池)---從class中的常量池加載?來---JDK1.7之后,轉移到堆中存儲 * 字?量類型 ? ?* 雙引號引起來的字符串值,?如"kkb" ----- 會進?字符串常量池(StringPool) ? ?* final修飾的變量 ? ?* ?final修飾的變量,?如long、double、float * 引?類型-->內存地址 ? ?* 類的符號引? ? ?* ?法 ? ?* 字段 JIT編譯器編譯之后的代碼緩存 如果需要訪問?法區中類的其他信息,都必須先獲得Class對象,才能取訪問該Class對象關聯的?法信息或者字段信息。#4.1.1.類型信息(重點)
類型的全限定名 超類的全限定名 直接超接?的全限定名 類型標志(該類是類類型還是接?類型) 類的訪問描述符(public、private、default、abstract、final、static)#4.1.2.類型的常量池
存放該類型所?到的常量的有序集合,包括直接常量(如字符串、整數、浮點數的常量)和對其他類 型、字段、?法的符號引?。 常量池中每?個保存的常量都有?個索引,就像數組中的字段?樣。因為常量池中保存著所有類型使?到的類型、字段、?法的字符引?,所以它也是動態連接的主要對象(在動態鏈接中起到核?作?)。#4.1.3.字段信息(該類聲明的所有字段)(重點)
字段修飾符(public、protect、private、default) 字段的類型 字段名稱#4.1.4.?法信息(重點)
?法信息中包含類的所有?法,每個?法包含以下信息
?法修飾符 ?法返回類型 ?法名 ?法參數個數、類型、順序等 ?法字節碼 操作數棧和該?法在棧幀中的局部變量區?? 異常表#4.1.5.類變量(靜態變量)(重點)
指該類所有對象共享的變量,即使沒有任何實例對象時,也可以訪問的類變量。它們與類進?綁定。#4.1.6.指向類加載器的引?
每?個被JVM加載的類型,都保存這個類加載器的引?,類加載器動態鏈接時會?到。#4.1.7.指向Class實例的引?
類加載的過程中,虛擬機會創建該類型的Class實例,?法區中必須保存對該對象的引?。通過 Class.forName(String className)來查找獲得該實例的引?,然后創建該類的對象。#4.1.8.?法表(重點)
為了提?訪問效率,JVM可能會對每個裝載的?抽象類,都創建?個數組,數組的每個元素是實例可能 調?的?法的直接引?,包括?類中繼承過來的?法。這個表在抽象類或者接?中是沒有的。#4.1.9.運?時常量池(Runtime Constant Pool)
class?件中除了有類的版本、字段、?法、接?等描述信息外,還有?項信息是常量池,?于存放編譯器?成的各種字?常量和符號引?,這部分內容被類加載后進??法區的運?時常量池中存放。 運?時常量池相對于class?件常量池的另外?個特征具有動態性,可以在運?期間將新的常量放?池中 (典型的如String類的intern()?法)。#5.?法區、永久代和元空間區別
?法區是抽象出來的概念。 ?永久代和元空間是?法區的具體實現。 永久代和元空間的區別是什么? 1.JDK1.8之前使?的?法區實現是永久代、JDK1.8及以后使?的?法區實現是元空間。 2.永久代所使?的內存區域是JVM進程所使?的區域,它的??受整個JVM的??所限制。元空間所使?的內存區域是物理內存區域。那么元空間的使???只會受物理內存??的限制。 3.永久代存儲的信息基本上就是上??法區存儲內容中的數據。元空間只存儲類的元信息,?靜態變量和運?時常量池都挪到堆中。 為什么要使?元空間來替換永久代? 1.Oracle收購了Java,?收購之前的Sun使?的JVM是Hotspot,?法區的實現是永久代,?Oracle?身也有?個JVM的實現,是JRockit,它的?法區就是元空間。收購之后,打算合?為?。 2.運?時常量池如果在JVM的內存中的話,如果使?不當,很容易出現內存溢出,因為永久代分配的??,?較?。#5.1.永久代和元空間存儲位置和存儲內容的區別
存儲位置不同,永久代是占據JVM進程內存空間的,?元空間屬于本地內存; 存儲內容不同,元空間存儲類的元信息,[靜態變量]和[常量池]等并?堆中。相當于永久代的數據被分到了堆和元空間中。微信掃一掃:關注我個人訂閱號“猿小飛”,更多精彩文章在這里及時發布:
?
總結
以上是生活随笔為你收集整理的JVM运行时数据区分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos中如何找出系统中 load
- 下一篇: 在git项目误上传了本地idea配置文件