本文引用的程式碼源自 Oracle 部落格上有關 Epsilon GC 的範例程式碼。
在本文中,我們探討了 Java 垃圾收集 (GC) 中一個特別有趣的選項,稱為 Epsilon GC。這種垃圾收集演算法以其顯著特徵而著稱:它不執行垃圾收集。 Epsilon 垃圾收集器 (GC) 包含在 JDK 11 中。
但是如果垃圾收集器不收集,它有什麼用呢? (不勞而獲啊!!)
不,它實際上非常有用,Oracle 部落格提供的這樣一個用例,我對其進行了稍微增強以使其更有幫助。
更多詳情請參考原博文:
https://blogs.oracle.com/javamagazine/post/epsilon-the-jdks-do-nothing-garbage-collector
用例:Epsilon GC 對於需要在不借助分析工具的情況下評估特定程式碼段的記憶體分配的開發人員來說是有益的。
主要挑戰傳統的垃圾收集器可以透過不斷清除物件來掩蓋準確的記憶體使用指標。這種幹擾使得很難確定程式碼的真實記憶體消耗。
Epsilon GC 透過充當非收集器來解決此問題。雖然它本身不是垃圾收集演算法,但它透過避免執行任何垃圾收集來充當理解記憶體分配的工具,從而提供記憶體使用情況的清晰圖片。
注意:需要注意的是,由於 Epsilon GC 不會回收內存,因此過多的分配可能會導致 JVM 中出現 OutOfMemoryError (OOM)。
以下是用來示範 Epsilon GC 功效的範例程式碼:
public class EpsilonDemo { public static String formatSize(long v) { if (v < 1024) return v + " B"; int z = (63 - Long.numberOfLeadingZeros(v)) / 10; return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z)); } public static void printmem(){ System.out.println("*** Free MEM = "+formatSize(Runtime.getRuntime().freeMemory())); } public static void main(String[] args) { final int MEGAABYTE = 1024 * 1024; final int ITERATIONS = 80; System.out.println("Starting allocations..."); printmem(); // allocate memory 1MB at a time for (int i = 0; i < ITERATIONS; i++) { var array = new byte[MEGAABYTE]; } System.out.println("Completed successfully"); printmem(); } }
期望:
該代碼分配 80MB 的位元組類型物件。當我們執行程式碼時,我們應該能夠透過列印語句觀察到相同的情況。
現在運行帶/不帶 EpsilonGC 的編譯版本:
java -Xms100m -Xmx100m -XX:+UseG1GC EpsilonDemo Starting allocations... *** Free MEM = 102.2 MB Completed successfully *** Free MEM = 74.2 MB
因此,透過 G1GC,我們看到了 28 MB 利用率的錯誤分配圖
java -Xms100m -Xmx100m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC EpsilonDemo [0.004s][warning][gc,init] Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups Starting allocations... *** Free MEM = 99.4 MB Completed successfully *** Free MEM = 18.7 MB
在這裡您可以清楚地看到 80.7 MB 的使用率
我希望這可以幫助您了解 EpsilonGC 如何非常方便地發現程式碼中的記憶體使用模式。乾杯! ?
以上是使用 Java EpsilonGC 查看記憶體分配。的詳細內容。更多資訊請關注PHP中文網其他相關文章!