目錄
概述
字節碼文件生成:首先Java源代碼文件(.java後綴)會被Java編譯器編譯爲字節碼文件(.class後綴),然後由JVM中的類加載器加載各個類的字節碼文件,加載完畢之後,交由JVM執行引擎執行。
在整個程序執行過程中,JVM會用一段空間來存儲程序執行期間需要用到的數據和相關信息,這段空間一般被稱作爲Runtime Data Area(運行時數據區),也就是我們常說的JVM內存。因此,在Java中我們常常說到的內存管理就是針對這段空間進行管理(如何分配和回收內存空間)。
執行引擎是將字節碼指令解釋、編譯成操作系統可以識別的本地機器指令。
JVM內存分配
根據 JVM 規範,JVM 內存共分爲虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。
各個分區介紹
名稱 | 特徵 | 作用 | 配置參數 | 異常 |
---|---|---|---|---|
程序計數器 | 佔用內存小,線程私有 | 字節碼行號指示器 | 無 | 無 |
虛擬機棧 | 線程私有,使用連續的內存空間 | java方法存儲的內存模型,存儲局部變量表、操作數棧、動態鏈接、方法出口等 | -Xss | OOM,stackOverFlow |
本地方法棧 | 線程私有 | 爲虛擬機使用到的本地方法服務,方便與外界環境交互 | 無 | OOM,stackOverFlow |
堆 | 線程共享 | 保存對象實例,所有對象實例都要在堆上分配 |
-Xmn -Xms -Xmx |
OOM java heap space |
方法區 | 線程共享 | 存儲已被虛擬機加載的類信息,常量,靜態變量,即時編譯器編譯後的代碼等數據 |
-XX:PermSize: 16M -XX:MaxPermSize 64M |
1.7 OOM PermGen space 1.8 OOM Metaspace |
運行時常量池 | 方法區的一部分 | 字面量及符號引用 |
1.7和1.8區別
其實,移除永久代的工作從JDK 1.7就開始了。JDK 1.7中,存儲在永久代的部分數據就已經轉移到Java Heap或者Native Heap。但永久代仍存在於JDK 1.7中,並沒有完全移除,譬如符號引用(Symbols)轉移到了native heap;字面量(interned strings)、類的靜態變量轉移到了Java heap。
JDK1.8和JDK1.7的jvm內存最大的區別是, 在1.8中方法區是由元空間(元數據區)來實現的,常量池移到堆中.
1.8不存在方法區,將方法區的實現給去掉了,而是在本地內存中,新加入元數據區(元空間).
元空間: 存儲.class 信息, 類的信息,方法的定義,靜態變量等.而常量池放到堆裏存儲