內存組成部分
根據(jù) JVM 規(guī)范,JVM內存共分為虛擬機棧、堆、方法區(qū)、程序計數(shù)器、本地方法棧五個部分。

虛擬機棧
每個線程都有一私有棧,隨著線程的創(chuàng)建而創(chuàng)建。棧里面會存放著“棧幀”,每個方法創(chuàng)建一個棧幀。
棧幀的組成部分:
一、局部變量:存放基本的數(shù)據(jù)類型(byte,char,int,double,float,boolean,long,short)和對象地址引用(一個指針指向對象或者一條指令)。局部變量區(qū)被定義一個從0開始的數(shù)字數(shù)組,byte、Char、short,boolean轉換成int,long ,double, 2個字節(jié)。其中64 位長度的long 和double 類型的數(shù)據(jù)會占用2個局部變量空間(Slot),其余的數(shù)據(jù)類型只占用1個。局部變量通過數(shù)組的下標訪問。
備注:局部變量表中的Slot是可重用的,方法體中定義的變量,其作用域并不一定會覆蓋整個方法,如果當前字節(jié)碼PC計算器的值已經超出了某個變量的作用域,那么這個變量對應的Slot就可以交給其它變量使用。
二、操作數(shù)棧:數(shù)組,先進后出,push和pop操作。
三、幀數(shù)據(jù)區(qū):
1、解析常量池的數(shù)據(jù)
2、方法執(zhí)行完后處理方法返回,恢復調用方現(xiàn)場
3、方法執(zhí)行過程中拋出異常時異常的處理,當出現(xiàn)異常時虛擬機查找相應的異常表看是否有對應的catch語句,如果沒有就拋出異常終止這個方法調用。
如果棧內存不夠將會拋出StackOverflowError錯誤。catch 捕獲的是 Throwable類。
調整棧內存大小參數(shù)-Xss:每個線程的stack大小(棧)
虛擬機堆
堆內存是 JVM所有線程共享的部分,在虛擬機啟動的時候就已經創(chuàng)建。所有的對象和數(shù)組都在堆上進行分配。這部分空間可通過 GC 進行回收。
當申請不到空間時會拋出 OutOfMemoryError。catch捕獲的是 Throwable。
調整堆參數(shù)大小參數(shù):
Xmx:Java Heap的最大值、默認為物理內存的1/4
Xms:Java Heap的初始值,server端最好Xms與Xmx一樣
Xmn:Java Heapyoung區(qū)的大小
XX:MetaspaceSize 元數(shù)據(jù)初始大小
XX:MaxMetaspaceSize 元數(shù)據(jù)內存最大值
在JDK1.8中,取消了PermGen,取而代之的是Metaspace。
元數(shù)據(jù)空間并不在虛擬機中,而是使用本地內存。
方法區(qū)
方法區(qū)也是所有線程共享。主要用于存儲類的信息、常量池、方法數(shù)據(jù)、方法代碼等。方法區(qū)邏輯上屬于堆的一部分,但是為了與堆進行區(qū)分,通常又叫“非堆”。
本地方法區(qū)
這部分主要與虛擬機用到的 Native方法相關,一般情況下, Java 應用程序員并不需要關心這部分的內容。
程序計數(shù)器
JVM支持多個線程同時運行,每個線程都有自己的程序計數(shù)器。倘若當前執(zhí)行的是 JVM 的方法,則該寄存器中保存當前執(zhí)行指令的地址;倘若執(zhí)行的是Native方法,則程序計數(shù)器中為空。
舉例
