簡單理解JVM虛擬機-JVM內存區域劃分

 程序計數器

 在 JVM 規範中,每個線程都有它自己的程序計數器,並且任何時間一個線程都只有一個方法在執行,也就是所謂的當前方法。程序計數器會存儲當前線程正在執行的 Java 方法的 JVM 指令地址;或者,如果是在執行本地方法,則是未指定值。

Java 虛擬機棧

每個線程在創建時都會創建一個虛擬機棧,其內部保存一個個的棧幀(Stack Frame),對應着一次次的 Java 方法調用。前面談程序計數器時,提到了當前方法;同理,在一個時間點,對應的只會有一個活動的棧幀,通常叫作當前幀,方法所在的類叫作當前類。如果在該方法中調用了其他方法,對應的新的棧幀會被創建出來,成爲新的當前幀,一直到它返回結果或者執行結束。JVM 直接對 Java 棧的操作只有兩個,就是對棧幀的壓棧和出棧。棧幀中存儲着局部變量表、操作數(operand)棧、動態鏈接、方法正常退出或者異常退出的定義等。

堆(Heap)

堆是Java 內存管理的核心區域,用來放置 Java 對象實例,幾乎所有創建的 Java 對象實例都是被直接分配在堆上。堆被所有的線程共享,在虛擬機啓動時,我們指定的“Xmx”之類參數就是用來指定最大堆空間等指標。理所當然,堆也是垃圾收集器重點照顧的區域,所以堆內空間還會被不同的垃圾收集器進行進一步的細分,如新生代、老年代。

方法區

這也是所有線程共享的一塊內存區域,用於存儲所謂的元(Meta)數據,例如類結構信息,以及對應的運行時常量池、字段、方法代碼等。由於早期的 Hotspot JVM 實現,很多人習慣於將方法區稱爲永久代(Permanent Generation)。Oracle JDK 8 中將永久代移除,同時增加了元數據區(Metaspace)。

運行時常量池

這是方法區的一部分。如果仔細分析過反編譯的類文件結構,你能看到版本號、字段、方法、超類、接口等各種信息,還有一項信息就是常量池。Java 的常量池可以存放各種常量信息,不管是編譯期生成的各種字面量,還是需要在運行時決定的符號引用,所以它比一般語言的符號表存儲的信息更加寬泛。

本地方法棧

本地方法棧和Java 虛擬機棧是非常相似,支持對本地方法調用,也是每個線程都會創建一個。在 Oracle Hotspot JVM 中,本地方法棧和 Java 虛擬機棧是在同一塊兒區域,這完全取決於技術實現的決定,並未在規範中強制

參考資料
Java核心技術面試精講

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章