jvm回收垃圾_没有垃圾回收的JVM
jvm回收垃圾
JVM社區(qū)不斷增加新的GC,最近又添加了一個新的GC,它被稱為Epsilon ,是非常特殊的一個。 Epsilon僅分配內(nèi)存,但不會回收任何內(nèi)存。
看起來好像不執(zhí)行任何垃圾回收的GC用途是什么。 這種類型的垃圾收集器有特殊用途,我們將進(jìn)行一些研究。
可以在哪里使用此靈巧的GC?
性能測試
如果您正在開發(fā)對延遲要求嚴(yán)格且內(nèi)存預(yù)算有限的解決方案,那么此GC可用于測試程序限制。
內(nèi)存壓力測試
想知道您的應(yīng)用程序提取瞬態(tài)內(nèi)存需求。 如果您要構(gòu)建一些純粹的內(nèi)存中解決方案,我會發(fā)現(xiàn)這很有用。
基準(zhǔn)標(biāo)記算法。
很多時候,我們希望基于對BIG(O)概念的理解來測試新的酷算法的真實性能,但是垃圾收集器會在測試過程中增加噪音。
低垃圾
很多時候,我們在算法上做了一些優(yōu)化以減少產(chǎn)生的垃圾,而像epsilon這樣的GC則有助于科學(xué)地驗證優(yōu)化。
如何啟用epsilon GC
JVM工程師特別注意不要在生產(chǎn)中默認(rèn)啟用此GC,因此要使用此GC,我們必須使用以下JVM選項
-XX:+ UnlockExperimentalVMOptions -XX:+ UseEpsilonGC -Xlog:gc
您可能會想到的一個問題是,當(dāng)內(nèi)存耗盡時會發(fā)生什么? JVM將因內(nèi)存不足錯誤而停止。
讓我們看一些代碼來測試GC
如何知道JVM進(jìn)程中是否使用epsilon?
Java具有良好的管理API,可以查詢正在使用的當(dāng)前GC,也可以用來驗證不同版本的Java中的默認(rèn)GC是什么。
public class VerifyCurrentGC { ? public static void main(String... args) { ? var gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); ? gcBeans.stream().forEach(gc -> { ? out.println(format( "GC Name : %s" , gc.getName())); var poolNames = gc.getMemoryPoolNames(); if (poolNames != null ) { List.of(poolNames).forEach(pool -> out.println(format( "Pool name %s" , pool))); } else { out.println( "No memory pools for " + gc.getName()); "No memory pools for " + gc.getName()); } ? }); ? } } 使用以下選項運行以上代碼
-XX:+ UnlockExperimentalVMOptions -XX:+ UseEpsilonGC VerifyCurrentGC 內(nèi)存耗盡時代碼的行為方式。
我將使用下面的代碼顯示新GC的工作方式。
public class MemoryAllocator { ? public static final int KB = 1024 ; static int mbToAllocate = Integer.getInteger( "mb" , 1000 ); ? public static void main(String[] args) { System.out.println(String.format( "Start allocation of %s MBs" , mbToAllocate)); ? for (var i = 0 ; i < mbToAllocate; i++) { var garbage = new byte [KB * KB]; } ? System.out.println( "I was Alive after allocation" ); } }在默認(rèn)的GC上運行以上代碼并請求分配5GB不會導(dǎo)致任何問題( java -Xlog:gc -Dmb = 5024 MemoryAllocator ),并且它會產(chǎn)生以下輸出
[0.016s] [info] [gc]使用G1
[0.041s] [info] [gc]定期GC已禁用
開始分配5024 MB [0.197s] [info] [gc] GC(0)暫停年輕(并發(fā)啟動)(G1混合分配)116M-> 0M(254M)3.286ms [0.197s] [info] [gc] GC(1)并發(fā)周期 [0.203s] [info] [gc] GC(1)暫停備注20M-> 20M(70M)4.387ms [0.203s] [info] [gc] GC(1)暫停清除22M-> 22M(70M)0.043ms [1.600s] [info] [gc] GC(397)并發(fā)周期6.612ms [1.601s] [info] [gc] GC(398)暫停年輕(并發(fā)啟動)(G1混合分配)52M-> 0M(117M)1.073ms [1.601s] [info] [gc] GC(399)并發(fā)周期 分配后我還活著 [1.606s] [info] [gc] GC(399)暫停備注35M-> 35M(117M)0.382ms [1.607s] [info] [gc] GC(399)暫停清理35M-> 35M(117M)0.093ms [1.607s] [info] [gc] GC(399)并發(fā)周期6.062ms
讓我們添加一些內(nèi)存限制( java -XX:+ UnlockExperimentalVMOptions -XX:+ UseEpsilonGC -Xlog:gc -Xmx1g -Dmb = 5024
內(nèi)存分配器)
[0.011s] [info] [gc]可調(diào)整大小的堆; 從253M開始,最大:1024M,步長:128M [0.011s] [info] [gc]使用TLAB分配; 最高:4096K [0.011s] [info] [gc]啟用了彈性TLAB; 彈性:1.10倍 [0.011s] [info] [gc]啟用了彈性TLAB衰減; 衰減時間:1000ms [0.011s] [info] [gc]使用Epsilon 開始分配5024 MB [0.147s] [info] [gc]堆:已保留1024M,已提交253M(24.77%),已使用52640K(5.02%) [0.171s] [info] [gc]堆:已保留1024M,已承諾253M(24.77%),已使用103M(10.10%) [0.579s] [info] [gc]堆:已保留1024M,已承諾1021M(99.77%),已使用935M(91.35%) [0.605s] [info] [gc]堆:已保留1024M,已承諾1021M(99.77%),已使用987M(96.43%)
由于java.lang.OutOfMemoryError而終止:Java堆空間
此特定運行導(dǎo)??致OOM錯誤,可以很好地確認(rèn)1GB之后該程序?qū)⒈罎ⅰ?
真正的多線程程序也具有相同的行為,有關(guān)示例,請參考MultiThreadMemoryAllocator.java 。
單元測試可用于測試此特殊GC的功能。
我認(rèn)為Epsilon將來會發(fā)現(xiàn)更多的用例和采用情況,這絕對是增加JVM覆蓋率的好一步。
所有代碼示例均可用Github回購
如果您喜歡該職位,則可以在Twitter上關(guān)注我 。
翻譯自: https://www.javacodegeeks.com/2019/08/jvm-with-no-garbage-collection.html
jvm回收垃圾
總結(jié)
以上是生活随笔為你收集整理的jvm回收垃圾_没有垃圾回收的JVM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 邮箱怎么开启imap(邮箱怎么开启IMA
- 下一篇: flashfxp怎么上传网页(怎么用fl