Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无明显原因的终身托收_Java_Garbage Collection - Fatal编程技术网

Java 无明显原因的终身托收

Java 无明显原因的终身托收,java,garbage-collection,Java,Garbage Collection,我有一个Java应用程序,它通常具有非常健康的垃圾收集统计数据。长期收集通常每小时左右进行一次,STW部分只需几分之一秒。但奇怪的是,收集总是在应用程序启动的前五分钟内发生。这是一个真正的问题,因为在那个时候,CPU的使用率已经远远高于正常水平(由于网络调用的增加,最终会被缓存),所以这些暂停时间总是比正常时间长,如果我在非常重的负载下重新启动,甚至会超过8秒 以下是JVM参数: -Xms4096m -Xmx4096m -XX:PermSize=768m -XX:MaxPermSize=7

我有一个Java应用程序,它通常具有非常健康的垃圾收集统计数据。长期收集通常每小时左右进行一次,STW部分只需几分之一秒。但奇怪的是,收集总是在应用程序启动的前五分钟内发生。这是一个真正的问题,因为在那个时候,CPU的使用率已经远远高于正常水平(由于网络调用的增加,最终会被缓存),所以这些暂停时间总是比正常时间长,如果我在非常重的负载下重新启动,甚至会超过8秒

以下是JVM参数:

-Xms4096m 
-Xmx4096m 
-XX:PermSize=768m 
-XX:MaxPermSize=768m 
-XX:SurvivorRatio=6 
-XX:NewSize=1024m 
-verbose:gc 
-XX:-DisableExplicitGC 
-XX:+PrintGCDetails 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCTimeStamps 
-XX:+PrintHeapAtGC 
-XX:+PrintTenuringDistribution 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:MaxDirectMemorySize=2048m 
-XX:+UseConcMarkSweepGC 
-XX:+CMSClassUnloadingEnabled 
-XX:+PrintConcurrentLocks 
-XX:+ExplicitGCInvokesConcurrent 
这里的问题是,是什么触发了这一终身收藏,因为在老一代中,当它出现时,几乎有2gb的空闲空间。以下是在正常情况下终身收藏前的用法:

concurrent mark-sweep generation total 3145728K, used 2897098K 
以下是在启动的最初几分钟内触发终身收藏之前的用法:

concurrent mark-sweep generation total 3145728K, used 1573655K 

我的理解是,只有当老一代人快满的时候,才应该进行终身收藏;否则什么会触发它呢?

CMS的一个关键概念是,它应该在空间用完之前开始收集,从而允许它同时运行。如果它一直等到你用完它就会触发一个序列停止世界收藏

因此,有两个阈值可以确定何时提前触发收集

-XX:CMSInitiatingOccupancyFraction=90 (by default)
-XX+UseCMSInitiatingOccupancyOnly
如果您不设置这些,那么何时开始使用“指标”将是一个好时机

我的理解是,只有当老一代人快满的时候,才应该进行终身收藏


这就是并行收集器所做的。

感谢您的回复。你是说JVM不知道终身收集需要多长时间,所以它在第一次不必要地提前启动它?我明白不能等到它真的满了,但在我的情况下,它几乎是半满的。如果是这样的话,设置这两个标志是否会迫使JVM等到旧版本已满90%后再进行第一次终身收集?@Cameron这就是它应该做的,是的。我倾向于将eden的大小设置得非常大,例如24GB,这样就可以轻松调整使用空间;)你把你的伊甸园设置为24gb…所以你从来没有达到完整的GC,因为所有的东西都在young gen中?事实上,我从来没有达到过一个小的收集,因为我大部分时间都使用堆外空间,所以需要一天来填满伊甸园空间。这可能只适用于HFT;)我每天晚上运行一个完整的gc,这是一整天唯一的gc。