JVM GC设置用于简单的用例

Kub*_*uba 5 garbage-collection jvm

我正在努力为我的JVM获得正确的设置.

以下是用例:Tomcat正在处理请求(300req/s).但它们非常快(键值查找)所以我没有任何性能问题.一切都会正常工作,直到我必须刷新它每3小时服务一次的数据.你可以想象我有一个很大的HashMap,我只是在做查找.在重新加载数据期间,创建一个临时的HashMap然后我交换它.我需要加载相当多的数据(每次内存大约800MB).

我有这个问题,在那些负载不时Tomcat停止响应.最初的问题是促销失败和FullGC,但我通过调整设置解决了这些问题.

正如您可能已经注意到,当CMS收集器启动时,我已经减少了值.我不会再获得任何促销失败或类似的东西.年轻一代相当小,可以快速进行小型收藏.我增加了SurvivorRatio,因为所有的请求对象都很年轻,不应该自动提升到老一代.(数据正在加载).

但是在数据加载期间,我仍然在Tomcat中看到503错误.在gc.log中,我的次要集合在此过程中开始变慢.与毫秒相比,它们现在只需几秒钟.我已经尝试减慢加载过程以使GC喘息,但我似乎没有工作......当我达到老一代的能力时,问题尤其成问题.CMS启动,释放内存,然后分配非常慢.我不再在gc.log中看到任何错误.我能做些什么不同的事情?我知道碎片可能是一个问题,但我没有得到促销失败.该机器是一个8核服务器.减少GCThread的数量是否有意义?为数据加载线程设置一个较低的线程优先级是否有意义?

有没有办法在后台定期启动CMS收集器?正在交换的数据实际上可以立即被垃圾收集.

我愿意接受任何建议!

这是我的JVM设置.

-Xms14g
-Xmx14g
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-XX:+AlwaysPreTouch 
-XX:MaxNewSize=256m
-XX:NewSize=256m 
-XX:MaxPermSize=128m 
-XX:PermSize=128m 
-XX:SurvivorRatio=24 
-XX:+UseCMSInitiatingOccupancyOnly 
-XX:CMSInitiatingOccupancyFraction=88 
-XX:+UseCompressedStrings 
-XX:+DisableExplicitGC 
Run Code Online (Sandbox Code Playgroud)

JDK 1.6.33 Tomcat 6

gc.log片段:

第7行数据加载开始

20号线停了下来

http://safebin.net/9124

K E*_*son 2

查看附加的日志并看到次要 GC 时间的巨大增加使我相信您的机器正承受来自 JVM 之外的其他进程的极重负载。

我的理由是,当您的 Minor GC 发生时,所有应用程序线程都会停止。因此,您的应用程序所做的任何操作都不会影响次要 GC 时间,因为您的新一代的大小是恒定的。

但是,如果在此期间机器上的其他进程有大量负载,GC 线程将竞争执行时间,您可能会看到这种行为。

当你的数据加载运行时,你能检查其他进程的CPU使用率吗?

编辑:更多地查看日志,我想出了另一种可能的解释。

目标幸存者空间似乎已满(ParNew 每个“慢”GC 正好下降到 10048K)。这意味着对象会直接提升到旧代,这可能会减慢速度。我会尝试增加新一代的规模并降低幸存者比例。甚至可以尝试在不设置新代大小或幸存者率的情况下运行,看看 JVM 如何设法优化它(尽管要注意 JVM 通常在优化此类突发方面做得很差)。