Java虛擬機(Java Virtual Machine)


JVM(Java Virtual Machine),Java虛機機,是JDK最底層的東西。只要能將源代碼編譯成字節碼(.class)文件,就可以由JVM在不同平台上解釋成機器指令來執行。所以,Java語言的平台無關性,實際上是因為有不同平台下的JVM的支持。

自動內存管理機制

Java程序的內存分配由JVM管理,所管理的內存划分為5個不同的數據區域。自動內存管理可歸結為解決兩個問題:給對象分配內存以及回收分配給對象內存。

程序計數器

用途:當前線程所執行的字節碼的行號指示器。

生命周期:與線程相同。為了線程切換后能恢復到正確的執行位置,每條線程都需要有一個獨立的程序計數器。(線程私有)

虛擬機棧

用途:描述Java方法執行內存模型:每個方法執行會創建一個棧幀入棧,用來存儲局部變量表、操作數棧、動態鏈接、方法出口等信息,方法執行完成時出棧。

生命周期:與線程相同。(線程私有)

本地方法棧

用途:與虛擬機棧類似,給Native方法使用。(線程私有)

生命周期:與線程相同。(線程私有)

堆區

用途:存放對象實例。

生命周期:虛擬機啟動時創建。(線程共享)

設置大小:-Xmx和-Xms。

方法區

用途:存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。

給對象分配內存

以HotSpot虛擬機為例

對象的創建

1、查找對應類的符號引用,沒有則加載相應的類。

2、分配內存給新對象。

3、初始化零值。

4、設置對象頭信息。(類元數據信息、哈希碼等)。

5、初始化對象。

對象的內存布局

1、對象頭:存儲對象自身的運行時數據,如哈希碼、線程持有的鎖、GC分代年齡等。

2、實例數據:程序中定義的各種類型的字段內容。

3、對齊填充:起占位符作用,為滿足對象起始地址是8字節的整數倍。

對象的訪問定位

使用直接指針訪問方式,即堆對象的引用直接指向對象地址。

回收分配給對象內存

垃圾收集(Garbage Collection,GC),上面三個線程私有區域在線程結束時內存就隨着回收了,所以垃圾回收一般指的是堆區和方法區。

何時回收?

判斷對象是存活還是死去,常有兩種方法。

一、引用計數算法

給對象中添加一個引用計數器,每當一個地方引用它就加1,引用失效則減1,計數器為0則對象已死。但是Java虛擬機不是用這種,最主要原因是很難解決對象的循環引用問題。

二、可達性分析算法

通過一系列“GC Roots”的對象作為起始點,往下搜索引用對象,搜索所經過的路徑稱為引用鏈,當一個對象不在任何一個引用鏈上時,則該對象已死。(Java虛擬機用這種)

GC Roots的對象包括:

1、虛擬機棧中引用的對象。

2、方法區中類靜態屬性或常量引用的對象。

3、本地方法棧中JNI引用的對象。

如何回收?

不同廠商、不同版本的虛擬機所提供的垃圾收集器可能會有很大差別,這一塊內容就不多深入。

虛擬機性能監控與故障處理工具

JDK的命令行工具

jps:列出正在運行的虛擬機進程。

jstat:監視虛擬機各種運行狀態信息。

jinfo:實時地查看和調整虛擬機各項參數。

jmap:生成堆的轉儲快照。

jhat:與jmap配和使用,分析jmap生成的堆轉儲快照。

jstack:生成虛擬機當前時刻的線程快照。

JDK可視化工具

JConsole:用來內存監控、線程監控。

VisualVM:強大的運行監控和故障處理程序,還有性能分析等功能。對性能影響小,可直接用於生產環境。

參考文獻

1、《深入理解Java虛擬機》 by 周志明


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM