Jvm學習
一、Jvm內存劃分
Jvm內存主要劃分爲以下幾個模塊
二、程序計數器(Program Counter Register)
程序計數器是線程私有的,每一個線程有一個。
與cpu中的pc寄存器相似,用來只是當前的線程執行到了字節碼的哪一行。
當jvm當前執行的是一個java方法,則程序計數器記錄的是當前放的字節碼地址;如果執行的是一個本地方法,則程序計數器存放的是Undefined。
三、虛擬機棧(JVM Stack)
虛擬機棧是線程私有的,每一個線程有一個。
一個線程的每個方法被執行的時候,都會創建一個棧幀。
棧幀中有局部變量表,操作站,動態鏈接,方法出口等。
方法被調用時,棧幀入棧,方法執行完成時,棧幀出棧。
局部變量表中存儲着方法的局部變量,包括基本類型,對象的引用,返回地址等。
在局部變量表中,只有long和double類型會佔用2個局部變量空間(Slot,對於32位機器,一個Slot就是32個bit),其它都是1個Slot。
虛擬機棧定義了2中異常。當線程調用的棧深度超過了棧的最大深度,會拋出StatckOverFlowError異常。當虛擬機棧沒有被固定大小時,會不停的申請內存擴展大小,直到達到最大內存,會有OutOfMemoryError異常。
四、本地方法棧(Native Method Statck)
本地方法棧是線程私有的,每一個線程有一個。
本地方法棧與虛擬機棧相似,唯一的區別是,虛擬機棧執行的是java方法,本地方法棧執行的native方法。但是在很多jvm中,兩種棧是合在一起的。
五、堆區(Heap)
堆區是線程私有的,每一個線程有一個。
堆區大致分爲兩個區域,或者叫兩代。一個叫年輕代,一個叫老年代。
年輕代存儲的剛創建的對象,年輕代又分爲兩個區域,Eden(伊甸)區和Survivor(倖存)區,survivor區有兩個。
① 對象剛剛被創建時,是分配在eden區的,eden區的內存是連續的,因此速度較快。
② 當eden區第一次滿了之後,將會執行Minor GC,將過期的對象銷燬,把倖存的對象複製到survivor0中(survivor0和survivor1總有一個是空的)。
③ 當eden再一次滿了,再進行一次Minor GC,會將倖存的對象複製到survivor1中。
④ 並且會將survivor0中的過期對象銷燬,夠資格的晉級年老代,倖存的進入survivor1中。
⑤ 當兩個survivor區來回切換了幾次後,大於等於15次(這個值可配置-XX:MaxTenuringThreshold)的對象將會進入老年區。
六、方法區(Method Area)
方法區是各個線程共享的區域。
之前,Hotspot虛擬機把堆內存劃分爲 青年代,老年代,持久代。而方法區指的就是這個持久代。但其他大多數虛擬機都沒有持久代,而Hotspot也已經取消了這個所謂持久代。
方法區,用於存儲已經被虛擬機加載的類信息(即加載類時需要加載的信息,包括版本、field、方法、接口等信息)、final常量、靜態變量、編譯器即時編譯的代碼等。