我正在我的glassfish服务器上运行一个应用程序,并且我有以下JVM设置(我认为这与我的问题相关):-Xmx512m -XX:NewRatio=2 -XX:+UseParallelOldGC -XX:+UseParallelGC
所有其他设置都是默认设置。我一直用JMC(Java Mission Control)测试服务器性能过去48小时,我注意到了这一点:PS Old Gen有大约341 MB的堆,PS Eden有大约143MB的堆,PS Surviovor有大约13MB的堆(这是我应该使用不同的SurvivorRatio吗?)
图表显示,在开始时,java堆有大约200MB的分配空间,但是在每个完整的GC之后,它会增长,所以现在大约是450MB,甚至堆使用(在每个完整GC之后)下降到大约100MB并且慢慢增长直到下一个小GC /完整GC ...为什么提交java堆(红线)增加?这是正常的行为吗?当它达到512MB时会停止吗?我应该使用-Xms512m那个提交的java堆从512开始会是512MB吗?
现在关于垃圾收集:
Minor GC(PS Scavenge)大约每1分钟运行一次,持续时间约为10-30ms。全GC(PS MarkSweep)大约每14-18小时运行一次,它的持续时间为200ms,但最后一次持续时间为20秒(我不知道为什么持续时间有这么大的差异)!我想知道这是否正常以及如何获得更好的结果?我应该使用-XX:+UseConcMarkSweepGC -XX:+UseParNewGC
还是-XX:+UseG1GC
?如果我使用这些GC中的任何一个,我将不得不增加最大堆大小(我读过UseG1GC仅用于更大的堆)?我是否必须更改除GC类型之外的任何其他设置(如SurvivorRatio,NewRation,...)?
JMC中的GC持续时间是否等于停止世界暂停时间(或暂停时间更短)?因此,如果我有20秒的GC GC持续时间,这意味着我的服务器没有响应20秒?我的服务器上有JAX-RS,我使用ajax每隔10秒调用其中一个(超时为10秒),这意味着至少有2个呼叫不会成功?在这种情况下,ajax调用的状态是什么(可能是错误)?我必须警告用户有关错误调用的信息,如果错误是GC暂停的结果,我不知道该怎么做....
如果我有-Xmx1024m(比现在大两倍),那么完整的GC会更少见,但会持续更长的时间吗?
我阅读了很多关于JVM和JVM GC的文章,但我仍然不知道我必须做什么,所有设置对我的应用程序来说都是最佳的(我担心最后20秒的GC持续时间)。 ..
感谢您的回答!
答案 0 :(得分:3)
Full GC(PS MarkSweep)大约每14-18小时运行一次,持续时间为200ms,但最后一次持续时间为20秒
尝试通过-XX:MaxGCPauseMillis
设置暂停时间目标。
我应该使用-XX:+ UseConcMarkSweepGC -XX:+ UseParNewGC或者甚至是-XX:+ UseG1GC?
那些肯定是一种选择,但由于并行收集器似乎能够提供良好的延迟,并且随着旧的增加而变得更糟,您可能不需要
图表显示,在开始时,java堆有大约200MB的分配空间,但是在每个完整的GC之后,它会增长,所以现在大约是450MB,甚至堆使用(在每个完整GC之后)下降到大约100MB并且慢慢增长直到下一个次要GC /完整GC ...为什么提交的java堆(红线)增加?
因为您正在使用并行收集器,它以吞吐量为主要目标(如果没有指定限制,可能会损害内存占用或延迟)。它可以通过在大量垃圾累积时很少收集来提供最高的吞吐量。
通过为其提供暂停时间目标,如果它变得太大而无法满足暂停时间目标,它将停止增长堆。
如果我有-Xmx1024m(比现在大两倍),那么完整的GC会更少见,但会持续更长的时间吗?
可能,但是一旦它不再符合MaxHeapFreeRatio
目标,GC将停止增加堆。