JVM 學習一:JAVA內存區域及內存溢出異常

老生常談 最近快要寫完畢業論文了 來學習一波JVM

開始正題:

Java內存區域主要值得是運行時數據區--->

1、程序計數器、

2、java虛擬機棧、

3、本地方法棧

4、堆

5、方法區

6、運行時常量池。

下面我們會按照這個循序進行介紹

1.程序計數器  

程序計數器是一塊較小的內存空間,當做是當前線程執行的字節碼指示器(線程私有)。分支、循環、遞歸、轉跳都需要以來這個計數器。

由於Java的多線程是通過線程輪流切換並非分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器都會斥力一條線程中的指令。因此,爲了線程切換後能恢復到正確的執行位置每個線程都有一個程序計數器。

如果線程正在執行的是一個Java方法,這個計數器的記錄是正在執行的虛擬機字節碼指令的地址;如果正在執行的是Native方法人,這個計數器的值爲空,此內存是沒有OutofMemoryErroor的情況的區域。

2.java虛擬機棧

java虛擬機棧也是線程私有的,它的生命週期與線程相同,在每個方法執行的時候都會創建一個棧幀,用於存儲局部變量表、操作數棧,每個方法的執行過程就對應着每個棧幀的入棧和出棧

局部變量表存放了編譯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)。對象引用類型

這個部分會出現兩種異常1StackOverflowError (如果線程請求的深度大於虛擬機允許的深度)2OutOfMemoryError(動態擴展時無法申請到足夠的內存)

3.本地方法棧

本地方法棧的作用於虛擬機棧的作用非常類似,區別在於虛擬機棧執行的是Java方法(字節碼)服務。本地方法棧執行的是Native方法服務,這個區域也會拋出1StackOverflowError 2OutOfMemoryError異常

4JAVA堆

對大多數應用,Java堆(Heap)是JVM中所管理的最大的一塊兒。Java堆是所有線程共享的一塊區域,在虛擬機啓動時創建。此區域唯一目標就是存放對象實例,所有的對象實例和數組都要在堆上分配。

JAVA堆是垃圾收集器管理的主要區域。因此很多時候也被稱作GC堆。垃圾回收時採用分代收集算法,故而GC堆可以被分爲新生代和老生代;再細緻一點的有Eden、From Survivor、To Survivor三個部分。從內存分配角度來哦看線程共享的JAVA對中可能劃分出多個線程私有的分配緩衝區,進一步的劃分是爲了更好的進行內存回收。

根據JVM的規定,Java堆可以處於物理上不連續的內存空間中,只要邏輯上是連續的即可,就像我們的磁盤空間一樣。實現的時候是可以擴展的,可以設定其最大最小值(通過-Xms 和 -Xmx來設置)。當無法進行擴展時,將會跑出OutofMemory的異常

5.方法區

方法區與Java堆一樣,是各個線程共享的內存區域,它用於存儲虛擬機加載的類信息、常量、靜態變量等,對於hotspot虛擬機來說把方法區看成永久代,但容易出現內存溢出的問題,因爲存在着上限,-XX:MaxPermSize  

6.運行時常量池

運行時常量池是方法區的一部分, 具備動態性。Java語言並不要求常量一定只有編譯期才能產生,也就是並非預置的class文件的常量池內榮才能進入方法區運行時常量池,運行期間也可能將新的常量放入池中。這種特性利用的比較多的是String類的intern方法

7.直接內存

昝略

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章