摘要:本文參照深入了解虛擬機周志明,純粹做做筆記,寫寫自己覺得較為重要的內(nèi)容方便理解虛擬機運行時數(shù)據(jù)區(qū)如下程序計數(shù)器程序計數(shù)器寄存器是一塊較小的內(nèi)存空間,看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行指示器。異常情況也與虛擬機棧一致。
本文參照深入了解Java虛擬機-周志明,純粹做做筆記,寫寫自己覺得較為重要的內(nèi)容方便理解
Java虛擬機運行時數(shù)據(jù)區(qū)如下:
1.程序計數(shù)器程序計數(shù)器(PC寄存器)是一塊較小的內(nèi)存空間,看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行指示器。
1.字節(jié)碼解釋器工作時改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,如分支丶循環(huán)丶跳轉(zhuǎn)丶異常處理丶線程恢復(fù)等。
2.多線程是通過線程輪流分配CPU時間方式來實現(xiàn)的,為了上下文切換后恢復(fù)到正確的執(zhí)行位置,每個線程有獨立的程序計數(shù)器,因此這塊內(nèi)存是線程私有的。
3.執(zhí)行過程若線程執(zhí)行Java方法,則計數(shù)器記錄的是當(dāng)前運行的虛擬機字節(jié)碼指令的地址;若執(zhí)行的是native方法,則計數(shù)器為空。
4.此內(nèi)存區(qū)域是唯一沒有內(nèi)存溢出的區(qū)域。
2.Java虛擬機棧虛擬機棧:也是私有的,它的生命周期與線程相同(調(diào)用至執(zhí)行完畢對應(yīng)著入棧和出棧過程。)。Java虛擬機棧描述的是Java方法執(zhí)行的內(nèi)存模型,每個方法執(zhí)行的時候都會在棧創(chuàng)建一個棧幀(方法運行時的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)).
可通過參數(shù) 棧幀是方法運行期的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)棧容量可由-Xss設(shè)置
.
1.棧幀:用于保存局部變量表丶操作數(shù)棧丶動態(tài)鏈接丶方法出口等信息。
局部變量表:32位變量槽,存放了編譯期可知的各種基本數(shù)據(jù)類型、對象引用(reference類型,不同于對象本身,可能是指向?qū)ο笃鹗嫉刂返囊弥羔槪部赡苁侵赶蛞粋€代表對象的句柄或其他與此對象相關(guān)的位置)、returnAddress類型(指向了一條字節(jié)碼指令的地址)。
操作數(shù)棧:基于棧的執(zhí)行引擎,虛擬機把操作數(shù)棧作為它的工作區(qū),大多數(shù)指令都要從這里彈出數(shù)據(jù)、執(zhí)行運算,然后把結(jié)果壓回操作數(shù)棧。
動態(tài)連接:每個棧幀都包含一個指向運行時常量池(方法區(qū)的一部分)中該棧幀所屬方法的引用。持有這個引用是為了支持方法調(diào)用過程中的動態(tài)連接。Class文件的常量池中有大量的符號引用,字節(jié)碼中的方法調(diào)用指令就以常量池中指向方法的符號引用為參數(shù)。這些符號引用一部分會在類加載階段或第一次使用的時候轉(zhuǎn)化為直接引用,這種轉(zhuǎn)化稱為靜態(tài)解析。另一部分將在每一次的運行期間轉(zhuǎn)化為直接應(yīng)用,這部分稱為動態(tài)連接
方法出口:返回方法被調(diào)用的位置,恢復(fù)上層方法的局部變量和操作數(shù)棧,如果無返回值,則把它壓入調(diào)用者的操作數(shù)棧。
備注:另外局部變量表的內(nèi)存空間在編譯期間就確定了,運行過程中不會改變,如double long占據(jù)2個局部變量空間,其余數(shù)據(jù)類型占用一個。
2.異常情況:如果線程請求的棧深度大于虛擬機所允許的深度,則拋出StackOverflowError;不過現(xiàn)在大部分可以支持動態(tài)擴展,若擴展時無法申請到足夠的內(nèi)存,則拋出OutofMemoryError.
3.本地方法棧:本地方法棧和Java虛擬機棧作用類似,區(qū)別是虛擬機棧為Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧為虛擬機使用到的native方法服務(wù)。異常情況也與虛擬機棧一致。
4.Java堆:可通過參數(shù) -Xms 初始堆大小和-Xmx 最大堆大小-Xmn 新生代` 設(shè)置
虛擬機中管理的內(nèi)存最大的一塊,所有線程共享,虛擬機啟動時創(chuàng)建。此內(nèi)存區(qū)域唯一目的是存放對象實例,幾乎所有對象實例及數(shù)組都要在堆上分配內(nèi)存。(隨著JIT編譯器發(fā)展和逃逸技術(shù),可能有些實例不在堆分配)。
1.垃圾收集:Java堆是垃圾回收的主要區(qū)域,從內(nèi)存回收的角度來看,由于現(xiàn)在收集器基本采用分代收集算法,
所以堆還可以細(xì)分為:
新生代:包括Eden區(qū)、From Survivor區(qū)、To Survivor區(qū),系統(tǒng)默認(rèn)大小Eden:Survivor=8:1:1。
老年代:在年輕代中經(jīng)歷了N次垃圾回收后仍然存活的對象,就會被放到老年代中。因此,可以認(rèn)為老年代中存放的都是一些生命周期較長的對象。
2.從內(nèi)存分配的角度來看,線程共享的堆可能會劃分出多個線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer.TLAB).
劃分目的:為了更好地回收內(nèi)存,或者更快得分配內(nèi)存。
3.Java堆可以處在物理上不連續(xù)的內(nèi)存空間,只要邏輯連續(xù)即可,堆也是可擴展的(通過 -Xmx -Xms控制)。
5.方法區(qū)(元空間,Metaspace):可通過參數(shù)-XX:MaxPermSize設(shè)置
與堆相同,也是線程共享的數(shù)據(jù)區(qū)域,用于存儲已被虛擬機加載的類信息丶常量丶靜態(tài)變量丶即時編譯器編譯后的代碼等數(shù)據(jù)。
垃圾收集:垃圾收集行為在此區(qū)域較少出現(xiàn),回收目標(biāo)主要是針對常量池的回收和對類型的卸載,但是對類型卸載很苛刻,對此區(qū)域未完全回收則出現(xiàn)內(nèi)存泄漏。
運行時常量池可通過參數(shù)-XX:PermSize和-XX:MaxPermSize設(shè)置
屬于方法區(qū)的一部分。class文件除了有類的版本,方法,字段,接口等描述信息外,還有常量池用于存放編譯器生成的各種字面量和符號引用,類加載后進(jìn)入方法區(qū)的運行時常量池存放。
常量池(ConstantPool):常量池數(shù)據(jù)編譯期被確定,是Class文件中的一部分。存儲了類、方法、接口等中的常量,當(dāng)然也包括字符串常量。
運行時常量池(Runtime Constant Pool):方法區(qū)的一部分,所有線程共享。虛擬機加載Class后把常量池中的數(shù)據(jù)放入到運行時常量池。
常量池中主要存放兩大類常量:字面量(Literal)和符號引用(Symbolic Reference)。
1.字面量:文本字符串、聲明為final的常量值等。
2.符號引用:類和接口的完全限定名(Fully Qualified Name)、字段的名稱和描述符(Descriptor)、方法的名稱和描述符,還有文本字符串的引用。
比如說:String a = "123";Class b =XX.Class,String c =類final變量中,abc都是符號引用
JDK1.6之前字符串常量池位于方法區(qū)之中。
JDK1.7字符串常量池已經(jīng)被挪到堆之中。
備注:運行時常量池還具備動態(tài)性,并非只編譯器才能產(chǎn)生,運行期也可以產(chǎn)生,比如String的intern方法。
6.直接內(nèi)存可通過-XX:MaxDirectMemorySize指定,如果不指定,則默認(rèn)與Java堆的最大值(-Xmx指定)一樣。直接內(nèi)存為非虛擬機內(nèi)存,如下:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73775.html
摘要:運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí)以及機制的基礎(chǔ),也是深入理解對象創(chuàng)建及運行過程的前提。了解內(nèi)存區(qū)域劃分,是學(xué)習(xí)概念的前提。 Java 運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí) jvm 以及 GC 機制的基礎(chǔ),也是深入理解 java 對象創(chuàng)建及運行過程的前提。廢話不多說,直接進(jìn)入正題: 一張圖總結(jié) showImg(https://segmentfault.com/img/bVOMAn?w=685&h=5...
摘要:堆和方法區(qū)只有在程序運行時才能確定內(nèi)存的使用情況,垃圾回收器所關(guān)注的主要就是這部分內(nèi)存。虛擬機會根據(jù)當(dāng)前系統(tǒng)的運行情況收集性能監(jiān)控信息,動態(tài)調(diào)整比率參數(shù)以提供最合適的停頓時間或最大的吞吐量。 Tip:內(nèi)容為對《深入理解Java虛擬機》(周志明 著)第三章內(nèi)容的總結(jié)和筆記。這是第一次拜讀時讀到的一些重點,做個分享,也為后面再次閱讀和實踐做保障。 3.1 概述 程序計數(shù)器、虛擬機棧、本地...
摘要:抽時間重新讀了一遍深入理解一書。驗證確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求,并且不會危害虛擬機自身的安全。可見性可見性是指當(dāng)一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。 抽時間重新讀了一遍《深入理解JVM》一書。以下為摘錄內(nèi)容。 1 java內(nèi)存區(qū)域 showImg(https://segmentfault.com/img/bVboDgk?w=617&h=365...
摘要:堆區(qū)堆是虛擬機所管理的內(nèi)存中最大的一塊,它是被所有線程共享的一塊內(nèi)存區(qū)域,該區(qū)域在虛擬機啟動的時候創(chuàng)建。 運行時數(shù)據(jù)區(qū)域 ? ?想要了解jvm,那對其內(nèi)存分配管理的學(xué)習(xí)是必不可少的;java虛擬機在執(zhí)行java程序的時候會把它所管理的內(nèi)存劃分成若干數(shù)據(jù)區(qū)域。這些區(qū)域有著不同的功能、用途、創(chuàng)建/銷毀時間。java虛擬機所分配管理的內(nèi)存區(qū)域如圖1所示 程序計數(shù)器 ? ?程序計數(shù)器是一塊比較...
摘要:前言本文內(nèi)容基本摘抄自深入理解虛擬機,以供復(fù)習(xí)之用,沒有多少參考價值。此區(qū)域是唯一一個在虛擬機規(guī)范中沒有規(guī)定任何情況的區(qū)域。堆是所有線程共享的內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。虛擬機上把方法區(qū)稱為永久代。 前言 本文內(nèi)容基本摘抄自《深入理解Java虛擬機》,以供復(fù)習(xí)之用,沒有多少參考價值。想要更詳細(xì)了解請參考原書。 第二章 1.運行時數(shù)據(jù)區(qū)域 showImg(https://segment...
閱讀 3536·2021-09-27 13:35
閱讀 3572·2019-08-29 17:09
閱讀 2457·2019-08-26 11:30
閱讀 712·2019-08-26 10:32
閱讀 546·2019-08-26 10:23
閱讀 1207·2019-08-26 10:20
閱讀 3163·2019-08-23 15:26
閱讀 3573·2019-08-23 14:33