Java 運行時的jvm劃分
程序計數器 記錄當前線程所執行的字節碼行號,用於獲取下一條執行的字節碼。 當多線程運行時,每個線程切換後需要知道上一次所運行的狀態、位置。 由此也可以看出程序計數器是每個線程 私有 的。 虛擬機棧 虛擬機棧由一個一個的棧幀組成,棧幀是在每一個方法調用時產生的。 每一個棧幀由 局部变量区 、 操作数栈 等組成。 每創建一個棧幀壓棧,當一個方法執行完畢之後則出棧。 如果出現方法遞歸調用出現死循環的話就會造成棧幀過多,最終會拋出 StackOverflowError 。 若線程執行過程中棧幀大小超出虛擬機棧限制,則會拋出 StackOverflowError 。 若虛擬機棧允許動態擴展,但在嘗試擴展時內存不足,或者在為一個新線程初始化新的虛擬機棧時申請不到足夠的內存,則會拋出 OutOfMemoryError 。 這塊內存區域也是線程私有的。 Java 堆 Java 堆是整個虛擬機所管理的最大內存區域,所有的對象創建都是在這個區域進行內存分配。 可利用參數 -Xms -Xmx 進行堆內存控制。 這塊區域也是垃圾回收器重點管理的區域,由於大多數垃圾回收器都採用 分代回收算法 ,所有堆內存也分為 新生代 、 老年代 ,可以方便垃圾的準確回收。 這塊內存屬於線程共享區域。 方法區(JDK1.7) 方法區主要用於存放已經被虛擬機加載的類信息,如 常量,静态变量 。 這塊區域也被稱為 永久代 。 可利用參數 -XX:PermSize -XX:MaxPermSize 控制初始化方法區和最大方法區大小。 元數據區(JDK1.8) 在 JDK1.8 中已經移除了方法區(永久代),並使用了一個元數據區域進行代替( Metaspace )。 默認情況下元數據區域會根據使用情況動態調整,避免了在1.7中由於加載類過多從而出現 java.lang.OutOfMemoryError: PermGen 。 但也不能無限擴展,因此可以使用 -XX:MaxMetaspaceSize 來控制最大內存。 運行時常量池 運行時常量池是方法區的一部分,其中存放了一些符號引用。 當 new 一個對象時,會檢查這個區域是否有這個符號的引用。 直接內存 直接內存又稱為 Direct Mem...