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