中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JVM運行時數據區原理解析

發布時間:2020-08-31 23:53:59 來源:腳本之家 閱讀:160 作者:fzsyw 欄目:編程語言

前言

Java虛擬機定義了若干種程序運行期間會使用的運行時數據區域,其中一些會隨著虛擬機啟動而創建,隨著虛擬機的退出而銷毀。另外一些則是和線程一一對應,這些與線程對應的數據區域隨著線程開始而創建,線程的結束而銷毀。

JVM運行時數據區原理解析

PC寄存器

PC寄存器是一塊較小的內存空間,可以看作是當前線程所執行的字節碼的行號指示器,每條線程都要一個獨立的PC寄存器,這個內存也是線程私有的內存。正在執行 java 方法的話,PC寄存器是記錄的是虛擬機字節碼指令的地址(當前指令的地址)。如果還是 Native 方法,則為undefined。這個內存區域是唯一一個在虛擬機中沒有規定任何OutOfMemoryError情況的區域。

虛擬機棧

虛擬機棧是描述 java方法執行的內存模型,每個方法在執行的同時都會創建一個棧幀(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。虛擬機棧的作用與傳統語言的棧類似,用于存儲局部變量和一些尚未計算的結果。另外它在方法調用和返回值中也扮演重要的角色。

虛擬機棧主要保存的內容是棧幀。棧幀是用來存儲數據和部分過程結果的數據結構,同時也被用來處理動態鏈接(Dynamic Linking)、 方法返回值和異常分派(Dispatch Exception)。棧幀隨著方法調用而創建,隨著方法結束而銷毀——無論方法是正常完成還是異常完成(拋出了在方法內未被捕獲的異常)都算作方法結束。

方法區

方法區是一塊所有線程共享的沒存區域。它用于存儲已被虛擬機加載的類信息、常量、靜態變量、即使編譯器編譯后的代碼等數據。方法區的大小決定了系統可以保存多少個類。

在JDK1.6、JDK1.7中,方法區可以理解為永久代(只針對HotSpot 虛擬機,其他的虛擬機可能不存在永久代的概念)。永久代可以使用參數-XX: PermSize和-XX MaxPermSize指定,默認情況下-XX MaxPermSize為64M。一個大的永久代可以保存更多的類信息。如果系統使用一些動態代理,那么有可能會在運行時生成大量的類,為了保證不會內存溢出,需要設置一個合理的永久代大小。HotSpot虛擬機把GC分代收集擴展至方法區, 即使用Java堆的永久代來實現方法區, 這樣 HotSpot 的垃圾收集器就可以像管理 Java 堆一樣管理這部分內存,而不必為方法區開發專門的內存管理器(永久帶的內存回收的主要目標是針對常量池的回收和類型的卸載, 因此收益一般小) 。

在JDK1.8中,永久代已經被移除,取而代之的是元空間(MetaSpace),元空間大小可以使用參數-XX MaxMetaSpaceSize指定。一個大的元空間可以使系統支持更多的類,只是一塊堆外的直接內存。如果不指定大小,默認情況下,虛擬機會耗盡所有的可用的系統內存。類的元數據放入直接內存, 字符串池和類的靜態變量放入java堆中,這樣可以加載多少類的元數據就不再由MaxPermSize控制,而由系統的實際可用空間來控制。

元空間與永久代最大的區別:永久代使用的是JVM的堆內存,而元空間使用的是本機的物理內存,所以元空間如果不設置大小,其大小受本機物理內存的限制。

運行時常量池

運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述等信息外,還有一項信息是常量池,用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后存放到方法區的運行時常量池中。Java 虛擬機對 Class 文件的每一部分(自然也包括常量池)的格式都有嚴格的規定,每一個字節用于存儲哪種數據都必須符合規范上的要求,這樣才會被虛擬機認可、裝載和執行。

運行時常量池相較于Class文件的常量池的另一個特征就是具備動態性。Java語言并不要求常量一定是在編譯期才能產生,也并非Class文件中常量池內容才能進入運行時常量池,比如String的intern()方法。

本地方法棧

本地方法棧和虛擬機棧作用類似,區別是虛擬機棧為執行Java方法服務, 而本地方法棧則為Native方法服務。虛擬機規范中堆本地方法棧使用的語言、使用的方式與數據結構并沒有強制規定,因此虛擬機可以自由的實現它。甚至有的虛擬機(比如HotSpot虛擬機)直接就把本地方法棧和虛擬機棧合二為一。

Java堆

Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建。此內存區域的唯一目的就是存放對象的實例,幾乎所有(不是全部都在這里分配)的對象的實例都是在這里分配內存。由于現代虛擬機采用分代收集算法, 因此Java堆從GC的角度還可以細分為: 新生代(Eden區、From Survivor區和To Survivor區)和老年代。

新生代是用來存放新生的對象。一般占據堆的 1/3空間。由于頻繁創建對象,所以新生代會頻繁觸發MinorGC進行垃圾回收。新生代又分為Eden區、ServivorFrom、ServivorTo 三個區。

Eden區是Java新對象的出生地(如果新創建的對象占用內存很大,則直接分配到老年代)。當Eden區內存不夠的時候就會觸MinorGC,對新生代區進行一次垃圾回收。ServivorFrom上一次 GC 的幸存者,作為這一次 GC 的被掃描者。ServivorTo。保留了一次 MinorGC過程中的幸存者。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黄平县| 余干县| 车致| 庐江县| 隆回县| 山丹县| 古浪县| 中宁县| 喀喇| 腾冲县| 隆安县| 本溪市| 台安县| 张家口市| 报价| 福贡县| 诸暨市| 定边县| 嘉善县| 邢台市| 涡阳县| 临桂县| 高雄县| 定南县| 堆龙德庆县| 南城县| 仲巴县| 阿拉善左旗| 乐昌市| 林芝县| 和硕县| 英吉沙县| 秀山| 临潭县| 台东市| 务川| 邻水| 商水县| 济南市| 铁岭市| 从江县|