Ama*_*mar 13 java performance garbage-collection jvm
我有两种类型的对象的大规模应用程序:长生活(缓存)和短生活(请求 - 进程 - 响应).从理论上讲,使用这种类型的应用程序,我认为可以配置Young和Old空间,因此旧空间消耗是恒定的,因此没有Full GC.
我已经更改了newSize-maxNewSize参数,但是,旧堆继续上升,直到Full GC.每次完整GC后,消耗量降至20%(缓存占20%).出于某种原因,我的对象进入旧空间.我有两个嫌疑人为什么搬到旧区:
根据这篇文章:http://chaoticjava.com/posts/gc-tips-and-memory-leaks/它被告知你是否分配了大对象,那些直接转到旧空间.这是真的,如果是,是否有JVM Option参数可以为Young空间设置对象大小阈值?
如果我正确理解了该过程,则在移动到旧部分之前,对象将在To-From生存部分之间切换.是否有参数可以设置在移动到旧空间之前要完成To和From之间的切换次数?
还有其他提示吗?
谢谢,阿玛尔
听起来你的幸存者空间不够大.你需要使它们足够大,不需要收集任何对象.对象仅在幸存者空间中切换一次.
如果要分配大对象,可以使用对象池来避免对它们进行GC操作.您是否考虑过将对象池用于请求/进程/响应数据?例如,一个简单的方法是使用ThreadLocal.
您是否尝试过G1收集器,它旨在逐步收集您的所有内存并减少完整GC的重大打击.
你确定老一代的增长只是没有缓存的对象吗?除非你的缓存是固定的并且永远不会改变,否则你将不断添加它.由于已经使旧代的对象从该缓存到期,因此它们将保留在内存中直到下一个完整的GC.
对于并发标记扫描收集器,我有更好的运气来完全消除完整GC的长暂停.它需要一些调整,它可以根据应用程序而变化.以下是我们用于运行24GB 64位JVM以及亚秒GC暂停的情况,同时使用大型缓存每秒提供100多页请求:
-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
Run Code Online (Sandbox Code Playgroud)