如何减少java并发模式故障和过多的gc [英] How to reduce java concurrent mode failure and excessive gc

查看:276
本文介绍了如何减少java并发模式故障和过多的gc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,并发模式失败意味着并发收集器无法释放足够的内存空间,形成永久和永久的gen,并且必须放弃并让所有的 stop-the-world gc kick最终结果可能非常昂贵。



我理解这个概念,但从来没有对

有一个很好的全面理解A)什么可能导致并发模式失败和

B)什么是解决方案?



这种不清楚导致我编写/调试代码时没有提示,经常不得不从Foo到Bar购买性能标志,没有特殊的原因,只是必须尝试。



我想从开发人员那里学习您的经验?如果你遇到这样的性能问题,原因是什么,如何解决它?



如果您有编码建议,请不要太笼统。谢谢!

解决方案

我学到的第一件事情是,它需要比其他收藏家更多的内存,约25到50 %多是一个好的起点。这有助于避免碎片,因为CMS不做任何压缩,如停止世界收藏家。第二,做有助于垃圾收集器的事情; Integer.valueOf而不是new Integer,摆脱匿名类,确保内部类不访问不可访问的东西(在外部类中的私有)东西。垃圾越少越好。



就调优而言,我发现你需要尝试几件事情:



-XX:+ UseConcMarkSweepGC



告诉JVM使用永久代理中的CMS。



修复堆大小:-Xmx2048m -Xms2048m这样可以防止GC执行类似于增长和缩减堆的操作。



-XX:+ UseParNewGC

在年轻一代中使用并行而不是串行收集。这将加快你的小集合,特别是如果你有一个非常大的年轻gen配置。一个大的年轻一代通常是好的,但不要超过旧基因大小的一半。



-XX:ParallelCMSThreads = X



设置当CMS可以并行执行的操作时将使用的线程数。



-XX:+ CMSParallelRemarkEnabled默认情况下是连续的,这可以加快你的速度。



-XX:+ CMSIncrementalMode允许应用程序通过在阶段之间建立GC来运行更多



-XX:+ CMSIncrementalPacing允许JVM改变它随时间收集的频率。



-XX:CMSIncrementalDutyCycleMin = X Minimm



-XX:CMSIncrementalDutyCycle = X从这个时间开始执行GC



-XX:CMSIncrementalSafetyFactor = X



我发现如果你设置它,你可以得到一般低的暂停时间,这样它基本上总是收集。由于大部分工作是并行完成的,因此基本上会定期产生可预测的暂停。



-XX:CMSFullGCsBeforeCompaction = 1



这一个非常重要。它告诉CMS收集器在启动新收集之前始终完成收集。没有这个,你可以遇到这样的情况,它抛出一堆工作,并重新开始。



-XX:+ CMSClassUnloadingEnabled



默认情况下,CMS会让你的PermGen增长,直到它从几个星期后杀死你的应用程序。这停止了​​。你的PermGen只会增长,虽然如果你使用Reflection,或者滥用String.intern,或做一些坏的类加载器或一些其他的东西。



幸存者比率和使用期限也可以玩,取决于你是否有长或短的生命对象,以及你可以生存的幸存者空间之间的对象复制多少。如果你知道你的所有对象都会坚持,你可以配置零大小的幸存者空间,任何幸存的一个年轻gen集合将被立即终止。


In Java, the concurrent mode failure means that the concurrent collector failed to free up enough memory space form tenured and permanent gen and has to give up and let the full stop-the-world gc kicks in. The end result could be very expensive.

I understand this concept but never had a good comprehensive understanding of
A) what could cause a concurrent mode failure and
B) what's the solution?.

This sort of unclearness leads me to write/debug code without much of hints in mind and often has to shop around those performance flags from Foo to Bar without particular reasons, just have to try.

I'd like to learn from developers here how your experience is? If you had encountered such performance issue, what was the cause and how you addressed it?

If you have coding recommendations, please don't be too general. Thanks!

解决方案

The first thing about CMS that I have learned is it needs more memory than the other collectors, about 25 to 50% more is a good starting point. This helps you avoid fragmentation, since CMS does not do any compaction like the stop the world collectors would. Second, do things that help the garbage collector; Integer.valueOf instead of new Integer, get rid of anonymous classes, make sure inner classes are not accessing inaccessible things (private in the outer class) stuff like that. The less garbage the better. FindBugs and not ignoring warnings will help a lot with this.

As far as tuning, I have found that you need to try several things:

-XX:+UseConcMarkSweepGC

Tells JVM to use CMS in tenured gen.

Fix the size of your heap: -Xmx2048m -Xms2048m This prevents GC from having to do things like grow and shrink the heap.

-XX:+UseParNewGC

use parallel instead of serial collection in the young generation. This will speed up your minor collections, especially if you have a very large young gen configured. A large young generation is generally good, but don't go more than half of the old gen size.

-XX:ParallelCMSThreads=X

set the number of threads that CMS will use when it is doing things that can be done in parallel.

-XX:+CMSParallelRemarkEnabled remark is serial by default, this can speed you up.

-XX:+CMSIncrementalMode allows application to run more by pasuing GC between phases

-XX:+CMSIncrementalPacing allows JVM to figure change how often it collects over time

-XX:CMSIncrementalDutyCycleMin=X Minimm amount of time spent doing GC

-XX:CMSIncrementalDutyCycle=X Start by doing GC this % of the time

-XX:CMSIncrementalSafetyFactor=X

I have found that you can get generally low pause times if you set it up so that it is basically always collecting. Since most of the work is done in parallel, you end up with basically regular predictable pauses.

-XX:CMSFullGCsBeforeCompaction=1

This one is very important. It tells the CMS collector to always complete the collection before it starts a new one. Without this, you can run into the situation where it throws a bunch of work away and starts again.

-XX:+CMSClassUnloadingEnabled

By default, CMS will let your PermGen grow till it kills your app a few weeks from now. This stops that. Your PermGen would only be growing though if you make use of Reflection, or are misusing String.intern, or doing something bad with a class loader, or a few other things.

Survivor ratio and tenuring theshold can also be played with, depending on if you have long or short lived objects, and how much object copying between survivor spaces you can live with. If you know all your objects are going to stick around, you can configure zero sized survivor spaces, and anything that survives one young gen collection will be immediately tenured.

这篇关于如何减少java并发模式故障和过多的gc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆