java記憶體溢出

java記憶體溢出

記憶體溢出(out of memory)通俗理解就是記憶體不夠,通常在運行大型軟體或遊戲時,軟體或遊戲所需要的記憶體遠遠超出了你主機內安裝的記憶體所承受大小,就叫記憶體溢出

基本介紹

  • 中文名:java記憶體溢出
  • 程式計數器:記錄當前執行緒所執行位元組碼
  • 虛擬機棧:描述的是Java方法執行的區域
  • 本地方法棧:本地方法Native,HotSpot等
運行時數據區域,1.1 程式計數器,1.2 java虛擬機棧,1.3本地方法棧,1.4 java堆(java Heap),1.5 方法區,1.7直接記憶體,對象訪問,OutOfMemoryError異常,3.1Java堆異常,3.2虛擬機棧和本地方法棧溢出,3.3方法區和運行時常量池溢出,3.4本機直接記憶體溢出,

運行時數據區域

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一樣

相關詞條

熱門詞條

聯絡我們