運行時數據區域
1.1 程式計數器
記錄當前執行緒所執行位元組碼的行號指示器。執行緒私有,占有很小一塊記憶體,唯一一塊沒有OutOfMemoryError的區域。
1.2 java虛擬機棧
執行緒私有,生命周期與執行緒一樣,描述的是Java方法執行的區域:每個方法被執行就回生成一個棧幀(Stack Frame)用於存儲局部變數表,操作棧,動態連結,方法出口等信息。
局部變數表存儲編譯器可知的各種基本數據類型(boolean byte char short int float long double)對象引用(reference)和returnAddress類型,其中float和double占用兩個局部變數空間Slot,其餘占用一個。
兩種異常:執行緒請求的深度大於虛擬機允許深度,StackOverFlowError,
無法申請到足夠的空間:OutOfMemoryError
1.3本地方法棧
與虛擬機棧的作用相同,只不過執行的是本地方法Native,HotSpot把java虛擬機棧和本地方法棧合二為一。
無法申請到足夠的空間:OutOfMemoryError unable to cteate new native thread
1.4 java堆(java Heap)
是記憶體中占用最大的一塊,被所有執行緒共享。所有的對象實例和數組都在這上面分配,但是隨著JIT編譯器的發展和逃逸技術的成熟等,也不是那么絕對了。
Java堆是記憶體回收的主要區域,也成為“GC堆”(Garbage Collected Heap)
如果無法申請到足夠的空間拋出OutOfMemoryError : Java heap space
1.5 方法區
用來存儲虛擬機載入的類信息,常量,靜態常量,即時編譯器編譯後的代碼等。也就是平時大家說的永久代,本質上並不等價,或者說使用永久代實現方法區而已。一般方法區記憶體回收成績不令人滿意。
如果如法申請到足夠的空間拋出OutOfMemoryError :PermGen space
1.6運行時常量池 (Runtime Constant Pool)
是方法區的一部分,Class檔案除了有類的版本信息、欄位方法接口外,還有一項信息是常量池,用於存放編譯器生成的各種字面量和符號引用,這部分信息在類載入後存放到方法區的運行時常量池中。
具有動態性,可以使用String類的intern()方法加入。
1.7直接記憶體
並不是虛擬機運行時數據區的一部分。JDK1.4中引入了NIO類,引入了一種基於通道與緩衝區的I/O方式,可以使用Native直接分配堆外記憶體,避免了再Java堆和Native堆中來回複製數據。
不會受到Java堆記憶體限制,但會受到機器總記憶體的限制。
如果如法申請到足夠的空間拋出OutOfMemoryError
對象訪問
Object obj = new Object();
Object obj 會反映到java棧的本地變數表中,作為一個reference數據類型出現。New Object 會反映到堆中。Reference規定了一個指向對象的訪問,主流訪問方式有兩種:
·句柄訪問,java堆中專門開闢出一塊句柄池,reference指向句柄池,句柄池中包含了實際的對象地址,優點:reference穩定不用更改。
·直接訪問,reference直接指向對象,優點:速度快,Hotspot採用這種方式 。
OutOfMemoryError異常
3.1Java堆異常
堆的最小值:-Xms 如-Xms20m
堆的最大值 -Xmx 如果設為一樣的則可避免堆自動擴展。
年輕代大小: -Xmn
-XX:+HeapDumpOnOutOfMemoryError 當記憶體溢出時Dump出當前的記憶體堆轉存快照。
Eclipse中虛擬機參數設定:debug As-->open dubug dialog
生成之後使用Eclipse Memory Analyzer 進行堆轉儲檔案分析(需要安裝MAT外掛程式)。
3.2虛擬機棧和本地方法棧溢出
-Xss:設定每條執行緒的Statck大小.在JDK1.5以後默認是1M,之前是256K
拋出StackOverFlow異常:作業系統分配給每個執行緒的記憶體是有限的,機器總記憶體減去Xmx再減去MaxPermSize,程式計數器占記憶體很少忽略,剩下的記憶體被虛擬機棧和本地方法棧瓜分,每個執行緒分到的棧容量越大,分配的執行緒數就小。正常情況棧深度1000-2000沒問題,如果是建立更多執行緒導致的記憶體溢出,在不能減少執行緒的情況下,只能通過減小Xmx和棧容量來換取更多執行緒。
3.3方法區和運行時常量池溢出
-PermSize :方法區的初始容量,默認是物理記憶體的1/64
-MaxPermSize :最大方法區容量。
3.4本機直接記憶體溢出
-XX:MaxDirectMemorySize 本機直接記憶體大小,如果不指定,則與Xmx一樣