1. 程式人生 > >Java虛擬機器-記憶體區域

Java虛擬機器-記憶體區域

jvm記憶體區域

方法區(Method Area) 常量池(Run-Time Constant Pool) 堆(Heap
程式計數器(Program Counter) 虛擬機器棧(Java Virtual Machine Statcks) 本地方法棧(Native Method Stacks)

方法區(Method Area)

儲存class型別、常量、靜態變數、即時編譯後的程式碼等資料。各個執行緒共享區域。

常量池(Run-Time Constant Pool):常量池屬於方法區,儲存常量和在編譯期生成的各種字面量和符號引用。

可能拋異常:

OutOfMemeoryError

原因

如果需要在方法區(PermGen)申請分配記憶體請求時,此時方法區(PermGen)記憶體不夠,則丟擲OutOfMemoryError。

通常是:

  • jsp頁面或通過CGLib、OSGI動態生成大量的類,有可能導致PermGen space記憶體不足。
  • 是由於使用String.intern()方法添加了過多內容。

解決方法:

  • 檢查是否使用String.intern()添加了過多內空,
  • 增大 -X:MaxPermSize 引數值。class也可以回收的,引數:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 。但不建議這樣種。

堆(Heap)

儲存所有物件和陣列例項。

可能拋異常

OutOfMemeoryError

原因

當jvm評估需要申請的記憶體超過jvm堆最大記憶體時,拋OutOfMemoryError。

解決方法

  • 檢查程式是否有死迴圈
  • 檢查程式是否存在資源未釋放
  • 檢查程式是否瞬間申請大量記憶體
  • 增大堆大小。引數: -Xmx

程式計數器(Program Counter)

記錄正在執行的虛擬機器位元組碼指令的地址。每個執行緒都有自已獨立的區域。

虛擬機器棧(Java Virtual Machine Statcks)

儲存區域性變量表(基本資料型別)、操作棧、動態連結、方法出口等資訊。

可能拋異常

StockOverflowError、OutOfMemeoryError

原因

  • StockOverflowError: 可能是執行緒請求的棧深度超出虛擬機器允許的最大深度。
  • OutOfMemeoryError: 可能是多執行緒環境在建立新執行緒時申請棧空間時記憶體不足。

解決方法

對於StockOverflowError異常,需檢查程式是否有遞迴呼叫次數過多。
對於OutOfMemeoryError 異常,則需要根據系統情況調整引數-Xss引數。

總結公式:

-Xss = (作業系統剩餘記憶體 - (-Xmx) - (-X:MaxPermSize) - 本地方法棧 ) / 預計的執行緒數

本地方法棧(Native Method Stacks)

C Statck,儲存native方法本地變數、操作棧等資訊。

可能拋異常

StockOverflowError、OutOfMemeoryError。

原因

  • StackOverflowError:
    如果一個執行緒申請一個很大的本地方法棧時,超過了最大限制則拋StackOverflowError。

  • OutOfMemoryError:
    如果本地方法棧可以動態擴充套件,並且本地方法棧申請擴充套件更多記憶體,但此時系統記憶體不足;或者是當在建立一個新的執行緒時,無法申請到初始化本地方法棧的記憶體時拋OutOfMemoryError。

解決方法

  • StackOverflowError :控制區域性變數數量和大小。

  • OutOfMemoryError : 增加記憶體。

參考