jvm運行時數據區表示

方法區的概念

根據JVM的規範,方法區用來存儲類的結構,好比運行時常量池,字段和方法數據,方法和構造函數的代碼,以及類和實例初始化,接口初始化中使用的一些特殊方法。規範把方法區從邏輯上看作是屬於堆的一部分,不一樣的實現能夠選擇是否要對這塊代碼作垃圾回收和壓縮,可是虛擬機規範自己並不強制規定方法區的位置(JDK 7 規範 JDK 8 規範 JDK 9 規範 JDK 10 規範 JDK 11 規範 在這一點上都是如此)。也就是說不一樣的實現能夠放在不一樣的地方html

如下來自hotspotjava

PermGem的概念

Hostspot中特有,它是方法區的一種實現。在jdk 7中,經過 -XX:MaxPermSize來決定最大的永久代大小,-XX:PermSize來控制方法區的初始大小。注意這裏講到 PermGem 是指permanent generation,它是從垃圾回收的角度來產生了一個generation的概念數組

在JVM中,有些對象很快被回收,有的則相對比較慢,爲了優化不一樣的對象回收的場景,就提出分代處理的概念 Generation詳見oracle

方法區與「堆」的關係

要看「堆」的上下語境。jvm

  • 若是堆指的是 GC heap,那麼它就是在堆中,值得注意的是,若是說 Native memory,這裏所指的角度就是 GC heap。
  • 若是這個堆是從廣義上講java heap的定義:哪兒存儲了java對象,哪兒就是 java heap,那它就是在堆中 (java.lang.String的一些實例會存在這裏)
  • 若是堆指的是運行時數據區中,用來分配類實例和數組的這塊區域,那麼它就再也不堆中,從這個角度講它也稱做 non-heap

常量池與PermGen的關係

常量池有不少種,要看常量池的角度函數

好比字符串常量,Integer常量,全量地址戳這裏優化

  • 若是是 runtime constant pool,它還在PermGen裏面
  • 若是是 SymbolTable、StringTable,它們一直存在 native memory
  • 若是是說 SymbolTable、StringTable的引用,jdk 7開始,SymbolTable引用的Symbol移動到了native memory,而StringTable則移到了普通的hava heap

StringTable 就是經過hash存儲一般的String的字符串常量表 ;SymbolTable用來保存定位和從新定位符號定義和符號引用所須要的信息this

運行時常量池 表示類文件中每一個類或者每一個接口運行時的表示,它包括編譯時已知的數字常量到必須在運行時解析的方法和字段引用spa

jdk8 對PermGen 的改進

hotspot中移除了PermGen,使用Metaspace,可使用-XX:MetaspaceSize-XX:MaxMetaspaceSize配置線程

permGen,「heap」,常量池之間的關係參考

棧幀

幀用來存儲數據和部分結果,包括動態鏈接、方法返回值和打包異常。 一個新的幀會在方法執行的時候建立,並在方法執行完畢的時候銷燬。每一個幀都會包含本身的局部變量,操做數棧和類當前運行方法對運行時常量池的引用。在編譯的時候,局部變量和操做數棧的大小就定下來了。任什麼時候候,給定一個線程只有一個幀是Active,它又被稱做當前幀

線程本身建立的幀是不能和其它線程共享的

局部變量

局部變量經過下標索引的方式訪問。第一個局部變量的索引是0,方法執行過程當中的傳參也是使用局部變量來實現的,他們從0開始一直按照遞增的方式連續的增加下標表示不一樣的參數。特別的下標0永遠表示傳遞的對象的引用,在java中就是 this

操做數棧

每一個幀都包含了一個 後進先出 的棧,包含操做數的幀剛創建的時候,它是空的,JVM會提供指令來把常量、字段值、局部變量加載如棧,而後由其它的指令取出並操做,而後把結果放回到棧中

傳遞給下一個方法的參數和接收方法的返回值也都是放在這裏

操做數棧中的每個值的類型和操做方法必定是匹配上的,這種關係在class文件上會作驗證。在任意的時刻,棧自己都會對應着棧的深度,它支持JVM中的任何類型,除去long和double會佔據兩個單元,其它類型都只佔據一個單元

動態鏈接

class文件的代碼中,對要執行的方法和變量都是經過符號引用獲取的,動態鏈接負責把這些符號引用轉換成對應的方法引用,加載那些還未定義過的符號,並把變量運行時的位置轉換成存儲結構中正確偏移處。

經過維持常量池的引用就能夠達到這種動態鏈接的實現

相關文章
相關標籤/搜索