-
1 # 墨跡天氣
-
2 # 小光童鞋
.方法區也稱"永久代”、“非堆”,它用於儲存虛擬機器載入的類資訊、常量、靜態變數、是各個 執行緒共享的記憶體區域。預設最小值為16MB,最大值為64MB,可以透過-XXFermSize 和-XX:MaxPermSize引數限制方法區的大小。執行時常量池:是方法區的一部分,Class檔案中除了有類的版本、欄位、方法、介面 等描述資訊外,還有一項資訊是常量池,用於存放編譯器生成的各種符號引用,這部分 內容將在類載入後放到方法區的執行時常量池中。・虛擬機器棧描述的是java方法執行的記憶體模型:每個方法被執行的時候都會建立一個“棧幀”用於 儲存區域性變量表(包括引數)、操作棧、方法出口等資訊。每個方法被呼叫到執行完的過 程,就對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程。宣告週期與執行緒相同,是線 程私有的。區域性變量表存放了編譯器可知的各種基本資料型別(boolean、byte、char、short、 int、*noat、long、double)、物件引用(引用指標,並非物件本身),其中64位長度的 long和double型別的資料會佔用2個區域性變數的空間,其餘資料型別只佔1個。區域性變數 表所需的記憶體空間在編譯期間完成分配,當進入一個方法時,這個方法需要在棧幀中分 配多大的區域性變數是完全確定的,在執行期間棧幀不會改變區域性變量表的大小空間。・本地方法棧與虛擬機器棧基本類似,區別在於虛擬機器棧為虛擬機器執行的java方法服務,而本地方法棧 則是為Nativ e方法服務。・堆也叫做java堆、GC堆是java虛擬機器所管理的記憶體中最大的一塊記憶體區域,也是被各個 執行緒共享的記憶體區域,在JVM啟動時建立。該記憶體區域存放了物件例項及陣列(所有new 的物件)。其大小透過-Xms(最小值)和-Xmx(最大值)引數設定,-Xms為JVM啟動時申 請的最小記憶體,預設為作業系統物理記憶體的1/64但小於1G,-Xmx為JVM可申請的最大 記憶體,預設為物理記憶體的1/4但小於1G,預設當空餘堆記憶體小於40%時,JVM會增大 Heap到-Xmx指定的大小,可透過-XX:MinHeapFreeRation=來指定這個比列;當空餘 堆記憶體大於70%時,JVM會減小heap的大小到-Xms指定的大小,可透過 XX:MaxHeapFreeRation=來指定這個比列,對於執行系統,為避免在執行時頻繁調整 Heap的大小,通常-Xm s與-Xmx的值設成一樣。由於現在收集器都是採用分代收集演算法,堆被劃分為新生代和老年代。新生代主要儲存 新建立的物件和尚未進入老年代的物件。老年代儲存經過多次新生代GC(Minor GC)任 然存活的物件。。新生代:程式新建立的物件都是從新生代分配記憶體,新生代由Eden Space和兩塊相同大小 的Survivor Space(通常又稱S0和S1或From和T。)構成,可透過-Xmn引數來指定 新生代的大小,也可以透過-XX:SurvivorRation來調整Eden Space及Survivor Space的大小。。老年代:用於存放經過多次新生代GC任然存活的物件,例如快取物件,新建的物件也有可 能直接進入老年代,主要有兩種情況:①.大物件,可透過啟動引數設定- XX:PretenureSizeThreshold=1024(單位為位元組,預設為0)來代表超過多大時就不 在新生代分配,而是直接在老年代分配。②.大的陣列物件,切陣列中無引用外部 物件。老年代所佔的記憶體大小為—Xmx對應的值減去-Xmn對應的值。・程式計數器是最小的一塊記憶體區域,它的作用是當前執行緒所執行的位元組碼的行號指示器,在虛擬機器 的模型裡,位元組碼直譯器工作時就是透過改變這個計數器的值來選取下一條需要執行的 位元組碼指令,分支、迴圈、異常處理、執行緒恢復等基礎功能都需要依賴計數器完成。
-
3 # Java碼農之路
Java虛擬機器相當於一個抽象的計算機作業系統,其管理的記憶體區域大體上可以分為棧和堆,就像c或c++中對記憶體的分類一樣,但這樣的分類對於Java虛擬機器來說太過粗淺,實際上Java虛擬機器管理的記憶體區域分為程式計數器、虛擬機器棧、本地方法棧、堆和方法區,根據各區域是屬於執行緒私有還是由執行緒共享,這些區域可以分為兩類,下面分別進行說明。
-
4 # 我們一起學Python
走向架構師,你必須瞭解的Java虛擬機器高階特性
連結: https://pan.baidu.com/s/1hAPo19keNFHb9ycBctkU2A 密碼: iayw
看完了你就知道Java虛擬機器了 不要謝我 、
對了
回覆列表
1.什麼是jvm?(1)jvm是一種用於計算裝置的規範,它是一個虛構出來的機器,是透過在實際的計算機上模擬模擬各種功能實現的。(2)jvm包含一套位元組碼指令集,一組暫存器,一個棧,一個垃圾回收堆和一個儲存方法域。(3)JVM遮蔽了與具體作業系統平臺相關的資訊,使Java程式只需生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。JVM在執行位元組碼時,實際上最終還是把位元組碼解釋成具體平臺上的機器指令執行。
2.jdk、jre、jvm是什麼關係?(1)JRE(Java Runtime Environment),也就是java平臺。所有的java程式都要在JRE環境下才能執行。(2)JDK(Java Development Kit),是開發者用來編譯、除錯程式用的開發包。JDK也是JAVA程式需要在JRE上執行。(3)JVM(Java Virtual Machine),是JRE的一部分。它是一個虛構出來的計算機,是透過在實際的計算機上模擬模擬各種計算機功能來實現的。JVM有自己完善的硬體架構,如處理器、堆疊、暫存器等,還具有相應的指令系統。Java語言最重要的特點就是跨平臺執行。使用JVM就是為了支援與作業系統無關,實現跨平臺。
3.JVM原理(1)jvm是java的核心和基礎,在java編譯器和os平臺之間的虛擬處理器,可在上面執行位元組碼程式。(2)java編譯器只要面向jvm,生成jvm能理解的位元組碼檔案。java原始檔經編譯成位元組碼程式,透過jvm將每條指令翻譯成不同的機器碼,透過特定平臺執行。
4. JVM執行程式的過程1) 載入.class檔案 2) 管理並分配記憶體 3) 執行垃圾收集JRE(java執行時環境)由JVM構造的java程式的執行環,也是Java程式執行的環境,但是他同時一個作業系統的一個應用程式一個程序,因此他也有他自己的執行的生命週期,也有自己的程式碼和資料空間。JVM在整個jdk中處於最底層,負責於作業系統的互動,用來遮蔽作業系統環境,提供一個完整的Java執行環境,因此也就虛擬計算機。作業系統裝入JVM是透過jdk中Java.exe來完成,透過下面4步來完成JVM環境:1) 建立JVM裝載環境和配置 2) 裝載JVM.dll 3) 初始化JVM.dll並掛界到JNIENV(JNI呼叫介面)例項4) 呼叫JNIEnv例項裝載並處理class類。5. JVM的生命週期1) JVM例項對應了一個獨立執行的java程式它是程序級別 a) 啟動。啟動一個Java程式時,一個JVM例項就產生了,任何一個擁有public static void main(String[] args)函式的class都可以作為JVM例項執行的起點 b) 執行。main()作為該程式初始執行緒的起點,任何其他執行緒均由該執行緒啟動。JVM內部有兩種執行緒:守護執行緒和非守護執行緒,main()屬於非守護執行緒,守護執行緒通常由JVM自己使用,java程式也可以表明自己建立的執行緒是守護執行緒 c) 消亡。當程式中的所有非守護執行緒都終止時,JVM才退出;若安全管理器允許,程式也可以使用Runtime類或者System.exit()來退出 2) JVM執行引擎例項則對應了屬於使用者執行程式的執行緒它是執行緒級別的
6、JVM記憶體模型
(1)java程式碼具體執行過程如下圖,
(2)執行時資料區,即jvm記憶體結構圖如下圖
(3)執行時資料區儲存了哪些資料?
a) 程式計數器(PC暫存器)
由於在JVM中,多執行緒是透過執行緒輪流切換來獲得CPU執行時間的,因此,在任一具體時刻,一個CPU的核心只會執行一條執行緒中的指令,
因此,為了能夠使得每個執行緒都線上程切換後能夠恢復在切 換 之前的程式執行位置,每個執行緒都需要有自己獨立的程式計數器,並且不能互相被幹擾,
否則就會影響到程式的正常執行次序。因此,可以這麼說,程式計數器是每個執行緒所私有的。由於程式計數器中儲存的資料所佔空間的大小不會隨程式的執行而發生改變,
因此,對於程式計數器是不會發生記憶體溢位現象(OutOfMemory)的。
b) java棧
Java棧中存放的是一個個的棧幀,每個棧幀對應一個被呼叫的方法,在棧幀中包括區域性變量表(Local Variables)、運算元棧(Operand Stack)、
指向當前方法所屬的類的執行時常量池(執行時常量池的概念在方法區部分會談到)的引用(Reference to runtime constant pool)、
方法返回地址(Return Address)和一些額外的附加資訊。當執行緒執行一個方法時,就會隨之建立一個對應的棧幀,並將建立的棧幀壓棧。當方法執行完畢之後,便會將棧幀出棧。
c)本地方法棧
本地方法棧與Java棧的作用和原理非常相似。區別只不過是Java棧是為執行Java方法服務的,而本地方法棧則是為執行本地方法(Native Method)服務的
d)堆
Java中的堆是用來儲存物件本身的以及陣列(陣列引用是存放在Java棧中的)。堆是被所有執行緒共享的,在JVM中只有一個堆。
e)方法區
與堆一樣,是被執行緒共享的區域。在方法區中,儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、常量以及編譯器編譯後的程式碼等。
在Class檔案中除了類的欄位、方法、介面等描述資訊外,還有一項資訊是常量池,用來儲存編譯期間生成的字面量和符號引用。
在方法區中有一個非常重要的部分就是執行時常量池,它是每一個類或介面的常量池的執行時表示形式,在類和介面被載入到JVM後,
對應的執行時常量池就被創建出來。當然並非Class檔案常量池中的內容才能進入執行時常量池,在執行期間也可將新的常量放入執行時常量池中,比如String的intern方法。
7、JVM記憶體溢位的情況
a) 程式計數器(Program Counter Register)
每條執行緒都有一個獨立的的程式計數器,各執行緒間的計數器互不影響,因此該區域是執行緒私有的。該記憶體區域是唯一一個在Java虛擬機器規範中沒有規定任何OOM(記憶體溢位:OutOfMemoryError)情況的區域。
b)Java虛擬機器棧(Java Virtual Machine Stacks)
在Java虛擬機器規範中,對這個區域規定了兩種異常情況:
1、如果執行緒請求的棧深度大於虛擬機器所允許的深度,將丟擲StackOverflowError異常。
2、如果虛擬機器在動態擴充套件棧時無法申請到足夠的記憶體空間,則丟擲OutOfMemoryError異常。
這兩種情況存在著一些互相重疊的地方:當棧空間無法繼續分配時,到底是記憶體太小,還是已使用的棧空間太大,其本質上只是對同一件事情的兩種描述而已。
在單執行緒的操作中,無論是由於棧幀太大,還是虛擬機器棧空間太小,當棧空間無法分配時,虛擬機器丟擲的都是StackOverflowError異常,而不會得到OutOfMemoryError異常。
而在多執行緒環境下,則會丟擲OutOfMemoryError異常。
c)堆Java Heap
Java Heap是Java虛擬機器所管理的記憶體中最大的一塊,它是所有執行緒共享的一塊記憶體區域。幾乎所有的物件例項和陣列都在這類分配記憶體。Java Heap是垃圾收集器管理的主要區域,因此很多時候也被稱為“GC堆”。
根據Java虛擬機器規範的規定,Java堆可以處在物理上不連續的記憶體空間中,只要邏輯上是連續的即可。如果在堆中沒有記憶體可分配時,並且堆也無法擴充套件時,將會丟擲OutOfMemoryError異常。
d)方法區域,又被稱為“永久代”,當方法區無法滿足記憶體分配需求時,將丟擲OutOfMemoryError異常。