1.java內存模型分析
java虛擬機運行時數據存儲區域包括線程隔離和線程共享兩類,整個PC的內存圖如下所示:
下面對以上內存區域說明:
1.1 register和cache
當代計算機一般有多個cpu,每個cpu有獨立的寄存器用于運行時存儲數據,同時每個cpu一般還會有1級或者多級高速存儲的緩存,當cpu讀取數據時,總是會先從緩存中讀取,如果緩存中沒有時才會讀取主內存中的數據,先把數據加載到緩存中,然后再從緩存中讀取數據;cpu寫數據時,也總是會先寫到緩存中,然后再某一個時間點刷新緩存,將緩存中的數據寫入到主內存中。由于這種工作方式,當多線程并發執行時候,可能會出現線程間數據不可見,以及訪問共享資源時會出現沖突的問題。詳細介紹參考:
2.線程隔離內存區域-programmer counter
每個線程都有一個程序計數器,當執行java方法的時候,次計數器的作用是用來保存次線程下一個需要執行的指令的地址。當執行navtive方法的時候,此計數器為undifined,下一條執行由本地程序計數器管理
3.JVM stack
每個線程都有一個虛擬機棧,此內存區域在線程創建的時候分配,此虛擬機棧用于調用方法,并執行方法的計算機指令,虛擬機棧可以動態分配,也可以指定初始化大小。
此塊內存區域會拋出以下兩種異常:
1.StackOverflowError,當計算時候請求的內存大小大于允許的最大值。
2.OutOfMemoryError,當動態分配內存的時候,已經沒有可用內存非配給新建的線程時候會拋出此異常。
4.堆
堆內存是所有線程共享的內存區域,此內存區域在虛擬機啟動的時候就由虛擬機進行分配,堆內存的大小可以固定大小,也可以動態分配,實現方式由具體的jvm來決定。我們所有使用new關鍵字創建的對象實例都保存在此內存區域內,此內存區域也是垃圾回收的主要區域。此內存區域會拋出以下異常:
OutOfMemoryError:當沒有空間分配給新建的對象實例的時候會拋出此異常。
5.方法區
方法區在邏輯上是數據堆的一部分,同樣是所有線程共享的內存區域,在虛擬機啟動的時候分配此內存,主要用于保存所有的類文件,包括類文件中的常量池、類方法、構造方法、類變量等數據。類加載的時候,會將這些信息保存到此內存區域。此內存區域由可能拋出以下異常:
OutOfMemoryError:當沒有可用內存空間分配給新的類信息時候,會拋出此異常。
6.運行時常量池
運行時常量池是用于保存類文件或者接口文件中的常量表中的數據,此數據包括編譯時可知的字面值常量和運行時需要解析的方法引用和Object變量引用等。此內存區域由方法區分配,在虛擬機加載類的時候會為每個類分配一個對應的類屬常量池。此內存區域會拋出以下異常:OutOfMemoryError,當沒有可用內存分配給內存申請的時候會拋出此異常。具體內存分配信息參考:
文章列表