摘要:下面的截圖內容來自從規范我們可以看到,規范要求的運行時數據區域有程序計數器虛擬機棧堆方法區本地方法棧運行時常量池這及部分。查了一下,還是沒有查到官方對于運行時數據區域的說明,但是許多博客都指出將字符串常量池移動到了堆中。
不少java程序員一提JVM運行時數據區域,就會說堆和棧,當然也有java程序員給出方法區、虛擬機棧、本地方法棧、堆、程序計數器這個答案,但是還有人給出永久代、虛擬機棧、本地方法棧、堆、程序計數器這個答案。那么究竟哪種答案是正確的呢?
首先我們介紹兩個概念,這對于我們回答上面的問題來說是必不可少的。
1.虛擬機: 簡單的說虛擬機是一種抽象的計算機。
2.Java虛擬機規范: 虛擬機規范是一種對Java虛擬機的約束,Java虛擬機負責對虛擬機規范進行實現。
我們平常所說JAVA虛擬機一般是指的一種具體的JAVA虛擬機規范的實現,比如說HotSpot。當然市面上還有其他的Java虛擬機。
下面的截圖內容來自https://docs.oracle.com/javas...
從JVM6規范,我們可以看到,規范要求的運行時數據區域有: PC Register(程序計數器)、Java Virtual Machine Stacks(java 虛擬機棧)、Heap(堆)、Method Area(方法區)、Native Method Stacks(本地方法棧)、Runtime Constant Pool(運行時常量池這及部分)。
注意標紅部分,我們可以看到運行時常量池位于方法區內。
根據規范我們可以大概的畫出JVM運行實數據區域(執行引擎、本地庫接口在后面的文章中會進行詳細介紹)。
在認真的看完JVM6、7、8的運行時數據區域規范之后,JVM6、7、8關于對運行時的數據區域要求一點變化都沒有,還是程序計數器、Java虛擬棧、堆、方法區、本地方法棧、運行時常量池這幾個部分。
那永久代是方法區的別名咯,準確的說是方法區的實現。規范是這么要求的,但是虛擬機會對這些區域進行調整,或者說是調整對JVM規范的實現。
查找了很多資料以后,還是沒有找到官方對于永久代的描述(有找到官方文檔關于永久代(Permanent Generation)的描述的,請聯系我)。綜合了很多博客和一些資料之后,我們可以做出如下判斷,永久代是HotSpot虛擬機特有的概念,HotSpot團隊使用永久代來實現JVM規范中的方法區。對于其他虛擬機來說是不存在永久代這個概念的。jdk8移除了永久代,關于這點我們將在后文進行詳細的介紹。
那么為什么稱方法區為永久代呢?
這跟GC分代收集有一定的關系,內存回收發生在方法區和堆中。
我們使用-XX:+PrintGCDetails參數,在IDEA中查看堆中的信息。
注意到PSYoungGen和ParOldGen這兩個單詞,從控制臺的信息我們可以看出堆中的區域劃分
PSYoungGen
eden space from space to space
ParOldGen
PS和Par代表垃圾回收器
也就是說堆里面又可以再分為年輕代、老年代,堆是垃圾回收機制的重點區域,將方法區也納入垃圾回收范圍,與年輕代、老年代相對,稱方法區為永久代。
這就是永久代的來歷。
接下來介紹一下JVM1.7和1.6的不同。
在介紹JVM1.6和1.7的區別之前,我們先介紹String類的intern()方法
字符串在調用該方法的時候,如果字符串常量池里面還沒有該字符串,則將該字符串添加進字符串常量池中。
查了一下,還是沒有查到HotSpot官方對于運行時數據區域的說明,但是許多博客都指出jdk1.7將字符串常量池移動到了堆中。
以下是分別在1.6、1.8的測試例子
1.6結果: false
1.7以上的結果:true
我們來解釋一下原因,1.6中字符串常量池放在永久代中和堆是隔離的。
我們來畫個圖來解釋一下,
1.6
1.7的虛擬機做了調整,常量池中不需要在存儲一份對象了,可以存儲堆中的引用,更為靈活。
1.7及以上的圖
請看下一張圖。
jdk版本在1.8。MetaSpace是什么鬼?
Jdk1.8移除了永久代或者說用MetaSpace去實現虛擬機規范中的方法區。
詳見:JEP 122: Remove the Permanent Generation
我查了很多資料,還是沒有找到官方對MetaSpace的解釋和描述,到是在深入探究 JVM | 探秘 Metaspace這篇博客中看到了MetaSpace的相關描述。
In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.
字符串常量池仍然在堆中,方法區移動至MetaSpace中
那么如果有人問你JVM運行時區域由幾部分組成,那么應該如何回答呢?
我認為答案可以是這樣的:JVM規范中的要求JVM運行時區域有以下及部分:
方法區
java虛擬機棧
本地方法棧
堆
程序計數器
運行時常量池(位于方法區中)
但是不同的虛擬機對規范有著不同的實現,HotSpot1.6對方法區的實現叫永久代,1.7將字符串常量池移動到了堆中,1.8移除了永久代改用元數據區實現方法區,字符串常量池仍然在堆中。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77895.html
摘要:方法區在實際內存空間站可以是不連續的。這一規定,可以說是給了虛擬機廠商很大的自由。但是值得注意的是,堆其實還未每一個線程單獨分配了一塊空間,這部分空間在分配時是線程獨享的,在使用時是線程共享的。 在我的博客中,之前有很多文章介紹過JVM內存結構,相信很多看多我文章的朋友對這部分知識都有一定的了解了。 那么,請大家嘗試著回答一下以下問題: 1、JVM管理的內存結構是怎樣的? 2、不同的...
摘要:棧因為是運行單位,因此里面存儲的信息都是跟當前線程相關的信息。基本類型和對象的引用都是在存放在棧中,而且都是幾個字節的一個數,因此在程序運行時,他們的處理方式是統一的。對象,是由基本類型組成的。 一、概念 數據類型 java虛擬機中,數據類型可以分為兩類: 基本類型 引用類型 基本類型的變量保存原始值,即:他代表的值就是數值本身;而引用類型的變量保存引用值。基本類型包括:byte,sh...
閱讀 3509·2021-11-25 09:43
閱讀 1266·2021-09-08 09:45
閱讀 2642·2021-09-07 09:59
閱讀 1501·2021-08-09 13:45
閱讀 3338·2019-08-30 15:54
閱讀 696·2019-08-29 18:35
閱讀 512·2019-08-29 17:18
閱讀 991·2019-08-29 14:10