重讀《深刻理解Java虛擬機》1、Java虛擬機內存區域的劃分

1、Java虛擬機內存區域如何劃分

一、Java虛擬機內存區域的劃分

 

區域名稱算法

做用(用途)緩存

類型佈局

特色spa

虛擬機規定異常狀況線程

內存分配與回收指針

其餘說明調試

1 程序計數器 指示當前正在執行的字節碼指令地址 線程私有 一、內存空間較小
二、隨用戶進程的啓動和結束而創建和銷燬。
隨用戶線程結束而自動回收,內存分配與回收具備肯定性。分配內存大小編譯期可知。 每一個線程都有獨立的程序計數器。執行Native方法時爲空指針。
2 虛擬機棧(棧內存) Java方法執行的內存模型(方法棧幀入棧、出棧)。每一個方法執行的時候都會建立一個棧幀用於存儲局部變量表、操做數,動態連接、方法出口等。
爲虛擬機執行Java方法服務,用於執行Java方法
線程私有 一、內存空間較小
二、隨用戶進程的啓動和結束而創建和銷燬
一、StackOverflowError:線程請求棧深大於虛擬機所容許的棧深。
二、OutMemoryError:如虛擬機棧能夠動態擴展,若是在擴展時沒法申請到足夠的內存時拋出異常
隨用戶線程結束而自動回收,內存分配與回收具備肯定性。
分配內存大小編譯期可知
局部變量表:用於存放編譯期可知的類型,包括基本類型,引用類型,returnAddress類型。局部變量表所需內存空間在編譯期已完成分配,運行期不改變局部變量表大小。
3 本地方法棧 爲虛擬機使用到的Native方法服務即用於執行Native方法 線程私有 一、內存空間較小
二、隨用戶進程的啓動和結束而創建和銷燬
一、StackOverflowError:
二、OutMemoryError:
隨用戶線程結束而自動回收,內存分配與回收具備肯定性。
分配內存大小編譯期可知,
 
4 堆(GC堆,堆內存) 用於存放對象實例,幾乎全部的對象實例都在這裏分配 線程共享 一、內存空間較大;
二、隨虛擬機進程啓動而建立
三、垃圾收集器主要管理的區域
四、不須要連續的內存空間,只要邏輯上連續便可
一、OutMemoryError:堆中沒有內存可用於完成實例分配,而且堆也沒法再擴展的時候拋出 動態分配。內存分配大小在運行期可知。垃圾收集器主要針對區域。 一、根據垃圾收集器實現算法(分代收集算法)分爲:Eden空間、From Survivor空間、ToSurvivor空間。(新生代,老年代)
二、從內存分配角度:堆可劃分爲多個線程私有的分配緩存區,目的是爲了更好的回收內存和更快的分配內存
5 方法區(非堆) 用於存儲虛擬機已經加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等(存放Class的相關信息如類名,訪問修飾符,常量池,字段描述,方法描述等) 線程共享 一、堆內存的一個邏輯部分
二、內存回收主要針對常量池的回收和類型的卸載
一、OutMemoryError:方法去沒法知足內存分配需求時拋出,即沒有足夠的內存用於分配 動態分配。內存分配大小在運行期可知。垃圾收集器主要針對區域。 運行常量池:用於存放編譯期生成的各類字面量和符號引用,在類加載後進入運行時常量池時存放。運行時常量池具有動態性即常量能夠在編譯期內產生也能夠在運行期添加新的常量···

 

直接內存不是Java內存區域。對象


二、堆內存空間內:對象實例的建立、內存佈局和內存定位

(1)堆內存空間內對象如何建立分配

1)根據new指令的類型常量在常量池內定位到該類型的符號引用、並判斷該類是否已加載、解析和初始化blog

2)若是判斷類型信息未加載則進行加載進程

3)在堆內分配指定大小的堆內存空間

如何分配堆內存空間:a、指針碰撞:即堆內存空間物理上是連續分配的,分配相對規整的,在用過的內存往未用過的內存方向進行分配

                            b、空閒列表:即堆內存空間不是規整分配的,使用一個空閒列表記錄當前未分配的內存空間,分配時在該空閒列表內查詢符合指定大小的內存空間進行分配

如何保證內存分配的正確性:線程私有分配緩衝區(TLAB),每一個線程獨立分配一塊小內存區域(本地線程分配緩衝),每一個線程只在本身的TLAB內分配實例對象。設置TLAB:-XX:+/-UseTLAB

4)自動初始化:初始化內存空間的默認值

5)設置對象頭信息

6)執行init初始化方法按照對象聲明位置進行初始化

Java堆內存實例對象初始化過程

 

(2)堆內存空間內對象如何佈局

1)對象頭

2)實例數據

3)對齊

(3)堆內存空間內對象如何定位

1)句柄

2)直接指針


三、OOM異常調試和參數設置

 

溢出區域

參數設置

異常拋出條件

其餘說明

-Xms
-Xmx
堆內存沒法自動擴展,沒有足夠內存分配實例對象 設置參數-XX:+HeapDumpOnOutMemoryError在出現異常時Dump出現當前內存堆轉儲快照用於過後分析
虛擬機棧和本地方法 -Xss:設置虛擬機棧大小
-Xoss:設置本地方法大小
一、StackOverflowError:線程請求棧深大於虛擬機所容許的棧深。
二、OutMemoryError:如虛擬機棧能夠動態擴展,若是在擴展時沒法申請到足夠的內存時拋出異常
每一個線程分配的虛擬機棧容量越大,則可創建的線程數就越少
方法區和運行時常量 -XX:PermSize方法區最小容量
-XX:MaxPermSize:最大方法區容量
一、OutMemoryError:方法去沒法知足內存分配需求時拋出,即沒有足夠的內存用於分配  
直接內存 -XX:MaxDirectMemorySize:指定直接內存最大容量,若是不指定默認與堆同等大小容量 一、OutMemoryError:方法去沒法知足內存分配需求時拋出,即沒有足夠的內存用於分配 不屬於Java內存區域直接內存=物理內存-各個區域內存總和
相關文章
相關標籤/搜索