1. 程式人生 > 實用技巧 >JVM中的堆和非堆記憶體

JVM中的堆和非堆記憶體

JVM記憶體包含以下部分:

  • 堆記憶體,它是Java物件的儲存
  • 非堆記憶體,Java用於儲存載入的類和其他元資料
  • 其他,JVM程式碼本身,JVM內部結構,載入的探查器代理程式碼和資料等。

JVM有一個堆,它是執行時資料區,從中分配所有類例項和陣列的記憶體。它是在JVM啟動時建立的。

可以使用以下VM選項配置堆大小:

1

2

-Xmx<size> - to set the maximum Java heap size

-Xms<size> - to set the initial Java heap size

預設情況下,最大堆大小為64 Mb。

物件的堆記憶體由自動記憶體管理系統回收,該系統稱為垃圾收集器。堆可以是固定大小,也可以擴充套件和縮小,具體取決於垃圾收集器的策略。

非堆

此外,JVM還有堆以外的記憶體,稱為非堆記憶體。它在JVM啟動時建立並存儲每類結構,例如執行時常量池,欄位和方法資料,方法和建構函式的程式碼,以及實習字串。

不幸的是,JVM在非堆記憶體上提供的唯一資訊是它的整體大小。沒有關於非堆記憶體內容的詳細資訊。

非堆記憶體大小的異常增長可能表示存在潛在問題,在這種情況下,您可以檢查以下內容:

  • 如果存在類載入問題,例如洩漏的載入器。
  • 如果有字串被大量實施。為了檢測這種問題,可以使用物件分配記錄。

如果應用程式確實需要大量非堆記憶體且預設最大大小為64 Mb是不夠的,則可以藉助-XX:MaxPermSize

VM選項擴大最大大小。例如,-XX:MaxPermSize=128m設定128 Mb的大小。

堆疊和堆之間的異同

Similarities and Differences Between Stack and Heap

兩者都是Java分配記憶體的方式,兩者都儲存在RAM中。但是,為了使事情更容易記住,堆用於動態記憶體分配,而堆疊用於靜態分配。

它存放在哪裡?在堆疊上分配的變數可以直接從記憶體訪問,因此,這些變數可以非常快速地執行。另一方面,訪問堆上的物件需要更多時間。

分配何時發生?在堆疊上,編譯程式時會發生記憶體分配。同時,在堆上,它在程式執行時開始。

既然如此,那麼在編譯之前,如果要使用堆疊,則需要知道需要多少資料和記憶體。堆疊的另一個限制是它無法處理需要大量記憶體的大塊變數。如果您不知道在執行時需要多少資料,或者您需要大量資料的記憶體,那麼您需要使用堆。

簡而言之…

堆疊stack

  • 堆疊的大小將隨著方法和函式根據需要建立和刪除區域性變數而變化。
  • 分配記憶體然後隨後釋放,而無需管理記憶體分配。
  • 堆疊的大小限制,可能會根據您使用的作業系統而有所不同。
  • 只要建立它們的函式正在執行,就會存在儲存在堆疊中的變數。

堆heap

  • 記憶體不是自動管理的,也不是由管理堆疊的方式由中央處理單元嚴格管理的。當不再需要這些塊時,您需要自己釋放已分配的記憶體。
  • 堆很容易發生記憶體洩漏,其中記憶體被分配給未使用的物件,並且除此之外的程序將無法使用。
  • 堆中沒有大小限制。
  • 與堆疊相比,堆中的物件訪問速度要慢得多。寫入堆上的記憶體也比較慢。

堆疊使用起來更容易,更快,但它帶來了很多限制,如果你使用堆,你可以忽略它們。

你什麼時候使用堆疊?堆疊只能用於佔用少量記憶體的區域性變數。好訊息是記憶體分配和管理不會成為您的問題,訪問這些物件的速度非常快。它確實受到大小限制以及無法在堆疊上調整變數的事實。

你什麼時候使用堆?如果存在需要全域性訪問的變數,則使用堆來分配記憶體,而不是隻對建立它的方法和函式可用。當你需要大量記憶體時,堆也很好,因為它對記憶體大小沒有限制。您還可以在堆上調整變數的大小。