Java中的元數據GC閾值
1. 概述
垃圾收集是 Java 運行時系統識別並刪除內存中未引用對象的過程。它通過清除未引用的對象、臨時對象、未使用的元數據等在管理內存中發揮著關鍵作用。
在本教程中,我們將探討Metaspace
和Metadata GC Threshold
,以及如何調整它們的參數。
2. 元數據
元數據包含有關**堆中對象的信息**,包括它們的類定義、方法表和相關信息。根據 Java 的版本,JVM 將此數據存儲在永久代或Metaspace
中。
JVM 依賴此信息來執行類加載、字節碼驗證和動態綁定等任務。
3. PermGen
和Metaspace
從 Java 8 開始,JVM 用內存中一個稱為Metaspace
的新區域替換了永久代或PermGen
,用於存儲元數據。
PermGen
是一個固定大小的內存區域,與主堆分開,用於存儲 JVM 加載的類和方法的元數據。它有一個固定的最大大小,一旦滿了,JVM 將拋出OutOfMemoryError
。
Metaspace
的大小不固定,可以動態增長,具體取決於應用程序中元數據的數量。 Metaspace
與主堆分開存在於本機內存(進程內存)的一段中。它的大小僅受主機操作系統設置的約束的限制。
4. Metadata GC Threshold
在Java中,當我們創建一個帶有元數據的對象時,它就像任何其他對像一樣佔用內存空間。 JVM 需要此元數據來執行各種任務。與常規對像不同,元數據在達到某個閾值之前不會進行垃圾回收。
隨著 Java 程序執行期間動態加載更多類, Metaspace
就會被填滿。
JVM 維護Metaspace
內容大小的閾值,當特定分配不符合該閾值時,它會觸發Metadata GC Threshold
垃圾收集週期。
5.元數據的JVM參數
我們可以使用-XX:+PrintClassHistogram
和-XX:+PrintMetaspaceStatistics
等 JVM 標誌來收集有關使用大量元數據內存的類的信息,並打印有關Metaspace
統計信息,例如用於類元數據的空間量。
使用這些信息,我們可以優化我們的代碼,以提高Metaspace
和垃圾收集週期的使用。此外,我們還可以調整與etaspace.
讓我們看一下用於調整元數據和Metaspace.
5.1 . -XX:MetaspaceSize=<size>
此參數有助於設置為類元數據分配的初始空間量(初始高水位線)(以字節為單位),這可能會導致垃圾收集卸載類。該數量是近似值,這意味著 JVM 也可以決定增加或減少Metaspace
的大小。
此參數的較大值可確保垃圾收集發生的頻率較低。該參數的默認值取決於平台,範圍從 12 MB 到大約 20 MB。
例如,我們可以將其設置為 128 MB:
-XX:MetaspaceSize=128m
5.2. -XX:MaxMetaspaceSize=<size>
此參數設置Metaspace
的最大大小,超過該大小將引發OutOfMemory
錯誤。該標誌限制為類元數據分配的空間量,並且分配給該參數的值是近似值。
默認情況下,沒有設置限制,這意味著Metaspace
可以增長到可用本機內存的大小。
作為示例,我們將其設置為 100 MB:
‑XX:MaxMetaSpaceSize=100m
5.3. -XX:+UseCompressedClassPointers
此功能旨在通過壓縮對象引用來減少 64 位 Java 應用程序的內存佔用。當此參數設置為true
時,JVM 將使用類元數據的壓縮指針,這允許 JVM 對類相關數據使用 32 位尋址,而不是完整的 64 位指針。
這種優化在 64 位體系結構上變得特別有價值,因為它減少了類元數據的內存使用量以及對象引用所需的內存,從而有可能提高應用程序的整體性能。
壓縮類指針將類空間分配與非類空間分配分開。因此,我們有兩個全局Metaspace
上下文:一個保存Klass
結構的分配(壓縮類空間),另一個保存其他所有內容(非類元Metaspace
)。
需要注意的是,在最新版本的 JVM 中,運行 64 位 Java 應用程序時通常會默認啟用該標誌,因此我們通常不需要顯式設置該標誌。
5.4. -XX:+UseCompressedOops
此 JVM 標誌啟用或禁用 64 位 JVM 中 Java 對象的壓縮指針的使用。當該參數設置為true時,JVM將使用壓縮指針,這意味著對象引用將使用32位指針而不是完整的64位指針。
使用壓縮指針,只能尋址較小範圍的內存。這迫使 JVM 使用較小的指針並節省內存。
六,結論
在本文中,我們探討了元數據和Metaspace
的概念。
我們探討了觸發Metadata GC Threshold
的原因。此外,我們還了解了Metadata
GC
Threshold
以及可用於調整Metaspace
和優化垃圾收集週期的不同 JVM 參數。