我有两种类型的大型应用程序:长生命(缓存)和短生命(请求-进程-响应)。从理论上讲,使用这种类型的应用程序,我认为配置Young和Old是可能的,因此旧空间消耗是恒定的,因此没有完整的GC。
我已经更改了newSize-maxNewSize params,但是,老堆一直上升到完全GC。在每个完整的GC之后,消耗降低到20% (缓存占20%)。因为某种原因,我的物体进入了旧空间。我有两个嫌疑人为什么要搬到旧空间去:
还有其他建议吗?
谢谢你,阿马尔
发布于 2011-06-03 11:04:33
听起来你的幸存者空间还不够大。您需要使它们足够大,以至于不需要收集任何对象。对象只在幸存者空间中切换一次。
如果您正在分配大型对象,您是否可以为它们使用对象池而不需要GC。您是否也考虑过对请求/进程/响应数据使用对象池?简单的方法是使用ThreadLocal。
您是否尝试过G1收集器,该收集器旨在逐步收集所有内存,并减少一个完整GC的大命中。
发布于 2011-06-03 14:09:39
您确定老一代的增长只是没有缓存对象吗?除非您的缓存是固定的,并且永远不会改变,否则您将不断地添加到它。当进入老一代的对象从缓存中过期时,它们将一直保存在内存中直到下一个完整的GC。
我有更好的运气与并发标记扫描收集器,以完全消除长暂停从完整的GC。它需要进行一些调整,并且可以根据应用程序的不同而有所不同。下面是我们用来运行一个24 GC的64位JVM的方法,它在每秒为100+页面请求提供大缓存的同时,暂停了亚秒GC:
-Xms24g -Xmx24g -XX:+UseCompressedOops -XX:NewRatio=4 -XX:SurvivorRatio=8
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+DisableExplicitGC
-XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSClassUnloadingEnabled
-XX:+CMSScavengeBeforeRemark -XX:CMSInitiatingOccupancyFraction=68发布于 2011-06-03 13:34:14
在搬到旧空间之前,是否可以设置往返之间的切换数?
是的,-XX:MaxTenuringThreshold
这个开关确定对象在“从”和“到”生还者空间之间跳过多少次,然后才被提升到老一代。Java 6和早期JDK的最大值分别为15和31。并行收集器的默认值为15,CMS收集器的默认值为4。。
在Sun JVM GC文档中,
使用-XX:MaxTenuringThreshold=0将年轻一代集合中幸存下来的对象立即移动到终身代。
就像你想要做的相反,如果你没有设置这个值,它将是默认的,这足以决定这个物体是否需要进入旧的--如果像@Peter说的那样,幸存者足够大来保存这些物体。
你的SurvivorRatio设置在什么地方?你的总堆是多少?
https://stackoverflow.com/questions/6226211
复制相似问题