java自動內存管理機制
java程序員把內存管理的工作交給虛擬機,一旦出現內存泄露或者溢出問題,如果不了解內存是怎樣工作的,那麽排查錯誤將是一件異常艱難的工作。
java內存區域與內存溢出異常
java運行時數據區域劃分:
線程隔離的
1.程序計數器(Program Counter Register)
當前線程執行代碼的行號指示器,當線程切換並分配處理器執行時間,為了保證線程恢復到正確的執行位置,每個線程都有獨立的計數器
2.虛擬機棧(VM Stack)
虛擬機棧描述的是java方法執行的內存模型:每個方式執行的同時會創建一個棧幀(Stack Frame),用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。
局部變量表存放了編譯期可知的基本數據類型,Reference類型,returnAddress類型。
其中long和double占用兩個slot,其他占用一個,局部變量表所需內存在編譯完全確定下來, 方法運行期間不會該表局部變量表大小。
這個區域規範了兩種異常狀況:
虛擬機棧數超過虛擬機允許數量,拋StackOverflowError
虛擬機內存擴展無法申請足夠的內存空間,拋OutOfMemoryError
3.本地方法棧(Native Method Stack)
本地方法棧與虛擬機棧作用類似,虛擬機棧為虛擬機執行java程序服務,本地方法棧為虛擬機執行本地方法服務。
本地方法棧也會拋出StackOverflowError,OutOfMemoryError異常。
線程共享的
4.堆(Heap)
java 堆是所有線程共享的一塊內存區域,在Java虛擬機規範中的描述是:The heap is the runtime data area from which memory for all class instances and arrays is allocated。
但是隨著jit編譯器發展和逃逸分析技術的成熟,棧內分配,標量替換使得對象不一定放在堆中存放
java堆是垃圾回收的主要管理區域,所以也成為GC堆,分代收集算法把內存分為一下幾個區域:
新生代
Eden 、From Survivor、To Survivor
老年代
如果堆中沒有內存完成分配,並且堆也無法擴展時,拋OutOfMemoryError
5.方法區(Method Area)
Method Area是所有線程共享的區域,存儲類信息,常量信息,靜態變量信息,編譯後代碼等。
SpotHot虛擬機把GC分代收集擴展至方法區,方便像管理堆一樣來管理方法區,所以有些人更願意成它為“永久代”(Permanent Generation)
java自動內存管理機制