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

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

问题描述

在Java中,并发模式失败意味着并发收集器未能从tenured和permanent gen中释放足够的内存空间,不得不放弃并让完整的stop-the-world gc启动in. 最终结果可能非常昂贵.

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.

我了解这个概念,但从未对
有过全面的了解A) 什么可能导致并发模式失败和
B) 解决方案是什么?

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?.

这种不清楚导致我在没有太多提示的情况下编写/调试代码,并且经常不得不在没有特殊原因的情况下购买从 Foo 到 Bar 的那些性能标志,只需要尝试.

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!

推荐答案

我了解到的关于 CMS 的第一件事是它需要比其他收集器更多的内存,大约 25% 到 50% 是一个很好的起点.这有助于您避免碎片化,因为 CMS 不会像世界收集器那样进行任何压缩.其次,做一些对垃圾收集器有帮助的事情;Integer.valueOf 而不是 new Integer,去掉匿名类,确保内部类没有访问不可访问的东西(在外部类中是私有的)这样的东西.垃圾越少越好.FindBugs 和不忽略警告将对此有很大帮助.

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

-XX:+UseConcMarkSweepGC

告诉 JVM 在tenured gen 中使用CMS.

Tells JVM to use CMS in tenured gen.

修复堆的大小:-Xmx2048m -Xms2048m 这可以防止 GC 执行诸如增大和缩小堆之类的操作.

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

-XX:+UseParNewGC

-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

-XX:ParallelCMSThreads=X

设置CMS在做可以并行完成的事情时将使用的线程数.

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

-XX:+CMSParallelRemarkEnabled 备注默认是串行的,这可以加快你的速度.

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

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

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

-XX:+CMSIncrementalPacing 允许 JVM 计算随时间变化的收集频率

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

-XX:CMSIncrementalDutyCycleMin=X 花费在 GC 上的最少时间

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

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

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

-XX:CMSIncrementalSafetyFactor=X

-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

-XX:CMSFullGCsBeforeCompaction=1

这一点很重要.它告诉 CMS 收集器在开始新的收集之前总是完成收集.没有这个,你可能会遇到这样的情况,它会扔掉一堆工作,然后重新开始.

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

-XX:+CMSClassUnloadingEnabled

默认情况下,CMS 会让您的 PermGen 增长,直到它在几周后杀死您的应用.这停止了​​.但是,如果您使用反射,或者滥用 String.intern,或者使用类加载器做一些不好的事情,或者其他一些事情,您的 PermGen 只会增长.

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天全站免登陆