java jvm原理,java JVM剖析

 2023-10-21 阅读 24 评论 0

摘要:1. 什么是JVM? JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。Java虛擬機包括一套字節碼指令集、一組寄存器、一個

1. 什么是JVM?

JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設備的規范,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。Java虛擬機包括一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收堆和一個存儲方法域。 JVM屏蔽了與具體操作系統平臺相關的信息,使Java程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。JVM在執行字節碼時,實際上最終還是把字節碼解釋成具體平臺上的機器指令執行。

Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平臺上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機后,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。Java虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的機器指令執行這就是Java的能夠“一次編譯,到處運行”的原因。

2. JRE/JDK/JVM是什么關系?

????????JRE(JavaRuntimeEnvironment, Java運行環境),也就是Java平臺。 所有的Java 程序都要在JRE下才能運行。普通用戶只需要運行已開發好的java程序,安裝JRE即可。
JDK(Java Development Kit)是程序開發者用來來 編譯、調試java程序用的開發工具包。JDK的工具也是Java程序,也需要JRE才能運行。為了保持JDK的獨立性和完整性,在JDK的安裝過程中,JRE也是 安裝的一部分。所以,在JDK的安裝目錄下有一個名為jre的目錄,用于存放JRE文件。
JVM(JavaVirtualMachine, Java虛擬機)是JRE的一部分。它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。JVM有自己完善的硬件架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。Java語言最重要的特點就是跨平臺運行。使用JVM就是為了支持與操作系統無關,實現跨平臺。


3. JVM原理

????????JVM是java的核心和基礎,在java編譯器和os平臺之間的虛擬處理器。它是一種利用軟件方法實現的抽象的計算機基于下層的操作系統和硬件平臺,可以在上面執行java的字節碼程序。

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的體系結構

類裝載器(ClassLoader)(用來裝載.class文件)
執行引擎(執行字節碼,或者執行本地方法)

運行時數據區

方法區(公有/類名/類修飾/靜態變量/final常量/方法信息)、

java jvm原理。堆(公有/new出來的對象/數組值)、

java虛擬機棧(私有/局部基本數據類型/返回值/堆棧幀)、

PC寄存器(JVM指令)、

本地方法棧


7. JVM運行時數據區


第一塊:PC寄存器

java jvm,PC寄存器是用于存儲每個線程下一步將執行的JVM指令,如該方法為native的,則PC寄存器中不存儲任何信息。


第二塊:JVM棧

JVM棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放的為當前線程中局部基本類型的變量(java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆上的地址


第三塊:堆(Heap)

它是JVM用來 存儲對象實例以及數組值的區域,可以認為Java中所有通過 new創建的對象的內存都在此分配,Heap中的對象的內存需要等待GC進行回收。

(1) 堆是JVM中 所有線程共享的,因此在其上進行對象內存的分配均需要進行加鎖,這也導致了new對象的開銷是比較大的
(2) Sun Hotspot JVM為了提升對象內存分配的效率,對于所創建的線程都會分配一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由JVM根據運行的情況計算而得, 在TLAB上分配對象時不需要加鎖,因此JVM在給線程的對象分配內存時會盡量的在TLAB上分配,在這種情況下JVM中分配對象內存的性能和C基本是一樣高效的,但如果對象過大的話則仍然是直接使用堆空間分配
(3) TLAB僅作用于新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效。

(4) 所有新創建的Object 都將會存儲在新生代Yong Generation中。如果Young Generation的數據在一次或多次GC后存活下來,那么將被轉移到OldGeneration。新的Object總是創建在Eden Space。


第四塊:方法區域(Method Area)

(1)在Sun JDK中這塊區域對應的為PermanetGeneration,又稱為 持久代

JVM(Java Virtual Machine)。(2)方法區域存放了所加載的類的信息(名稱、修飾符等)、類中的靜態變量、類中定義為final類型的常量類中的Field信息類中的方法信息,當開發人員在程序中通過Class對象中的getName、isInterface等方法來獲取信息時,這些數據都來源于方法區域,同時方法區域也是全局共享的,在一定的條件下它也會被GC,當方法區域需要使用的內存超過其允許的大小時,會拋出OutOfMemory的錯誤信息。


第五塊:運行時常量池(Runtime Constant Pool)

存放的為類中的固定的常量信息、方法和Field的引用信息等,其空間從方法區域中分配。


第六塊:本地方法堆棧(Native Method Stacks)

JVM采用本地方法堆棧來支持native方法的執行,此區域用于存儲每個native方法調用的狀態


8. JVM垃圾回收

GC (Garbage Collection)的基本原理:將內存中不再被使用的對象進行回收,GC中用于回收的方法稱為收集器,由于GC需要消耗一些資源和時間,Java在對對象的生命周期特征進行分析后,按照新生代、舊生代的方式來對對象進行收集,以盡可能的縮短GC對應用造成的暫停
(1)對新生代的對象的收集稱為minor GC;
(2)對舊生代的對象的收集稱為Full GC;
(3)程序中主動調用System.gc()強制執行的GC為Full GC。
不同的對象引用類型, GC會采用不同的方法進行回收,JVM對象的引用分為了四種類型:
(1)強引用:默認情況下,對象采用的均為強引用(這個對象的實例沒有其他對象引用,GC時才會被回收)
(2)軟引用:軟引用是Java中提供的一種比較適合于緩存場景的應用(只有在內存不夠用的情況下才會被GC)
(3)弱引用:在GC時一定會被GC回收

jvm的理解?(4)虛引用:由于虛引用只是用來得知對象是否被GC


9.總結:

大多數 JVM 將內存區域劃分為 :

Method Area(Non-Heap)(方法區) ,

Heap(堆) ,?

Program Counter Register(程序計數器) ,? ?

深入理解JVM?VM Stack(虛擬機棧,也有翻譯成JAVA 方法棧的),

Native Method Stack? ( 本地方法棧 ),

其中Method Area 和? Heap 是線程共享的? ,VM Stack,Native Method Stack? 和Program Counter Register? 是非線程共享的。

10.為什么分為 線程共享和非線程共享的呢?

????????首先我們熟悉一下一個一般性的 Java 程序的工作過程。一個 Java 源程序文件,會被編譯為字節碼文件(以 class 為擴展名),每個java程序都需要運行在自己的JVM上,然后告知 JVM 程序的運行入口,再被 JVM 通過字節碼解釋器加載運行。

11.那么程序開始運行后,都是如何涉及到各內存區域的呢?

????????概括地說來,JVM初始運行的時候都會分配好 Method Area(方法區) 和Heap(堆) ,而JVM 每遇到一個線程,就為其分配一個 Program Counter Register(程序計數器) ,? ?VM Stack(虛擬機棧)和Native Method Stack? (本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所占用的內存空間也會被釋放掉。這也是為什么我把內存區域分為線程共享和非線程共享的原因,非線程共享的那三個區域的生命周期與所屬線程相同,而線程共享的區域與JAVA程序運行的生命周期相同,所以這也是系統垃圾回收的場所只發生在線程共享的區域(實際上對大部分虛擬機來說知發生在Heap上)的原因。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/158869.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息