锁定老帖子 主题:JVM的GC-生命不能承受之重
精华帖 (17) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (9)
|
|
---|---|
作者 | 正文 |
发表时间:2008-11-06
helloboy9527 写道 liuruncheng 写道 Java有RTS(Real Time System)规范,要做实时系统还是用这个做比较靠谱
我们的认证系统是纯C开发的,8台16CPU、32G内存的机器分两组集群,每台缓存超过10G内存,虽然不会有任何停顿, 但是内存泄漏同样是个梦魇,每年都在查内存泄漏,几乎成了无法避免的任务了 就是因为当初怕内存泄漏这个梦魇,才避开C,选择用JAVA来开发此类系统,简洁轻便,开发也非常快。可惜JVM的GC已经成为生命不能承受之重,唉。 Java RTS已经有成熟的产品,IBM和SUN都有不错的解决方案,你可以试试 |
|
返回顶楼 | |
发表时间:2008-11-06
看看这篇文章可能会有帮助:http://java.sun.com/products/hotspot/whitepaper.html
JVM的GC算法有很多种:Generational Copying Collection,Parallel Young Generation Collector,Mark-Compact Old Object Collector,Mostly Concurrent Mark-Sweep Collector和Parallel Old Generation Collector。你可以选择带有并行算法的收集器,如Mostly Concurrent Mark-Sweep Collector和Parallel Old Generation Collector这样可以减少垃圾回收的等待时间,提高响应性。 |
|
返回顶楼 | |
发表时间:2008-11-06
建议尝试BEA JRockit Real Time,一个实时JVM,现在已经收到Oracle旗下了。(http://www.oracle.com/technology/products/jrockit/jrrt/index.html)
从内部测试结果来看,还是挺不错的。基本思路就是并行GC,从理论上来说,不会再出现full GC的现象。 |
|
返回顶楼 | |
发表时间:2008-11-06
最后修改:2008-11-06
调整gc参数显然治标不治本,治本的方法前面的大侠们已经说了。
我提供一下我的jvm参数,仅供参考。我的服务器是8G内存,两个四核cpu,PE2950,64位系统 两个JVM,每个JVM的参数如下: -server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Djava.awt.headless=true -XX:+DisableExplicitGC 这个参数的效果对我的应用比较好 |
|
返回顶楼 | |
发表时间:2008-11-06
CostaR 写道 调整gc参数显然治标不治本,治本的方法前面的大侠们已经说了。
我提供一下我的jvm参数,仅供参考。我的服务器是8G内存,两个四核cpu,PE2950,64位系统 两个JVM,每个JVM的参数如下: -server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Djava.awt.headless=true -XX:+DisableExplicitGC 这个参数的效果对我的应用比较好 修改下比较好: -XX:PermSize=128m 建议改成最大128M,避免没有使用。 -XX:ParallelGCThreads=4 改成跟你的CPU CORE 数量一致, 我记得缺省就是CPU的数量, 具体可以查询下MANUAL。 另外, 对于特殊的应用, 比如楼主的应用, 需要你调整你的老生代区域的大小。 确定的方法如下: 楼主你用命令 jstat -gctuil pid 1000 1000 看几分钟 看下, 老生代在最小的时候, 一般是FULL GC过后的几秒, 你可以看到老生代区域使用的百分比。 比如是 50%,如果, 老生代一直处于70%的以上的水平, 那么需要把老生代调大, 另外, 我建议你, 把Full GC的收集比例调到, 默认值是70%, 对于你的应用, 我建议你调制到80%。 然后, 你用jmap看下, 老生代总共占用了多少内存。 一般来说, 你需要把老生代的内存调节到一个合适你的大小。 建议不要超过70%的使用量就可以了。 这样就能腾出大量的内存给新生代。 这个怎么设置你看下资料, 不然, 你无法自己确定作出微小调整。 这个做法只能尽量避免FULL GC。 这个参数配置方法比较痛苦的是无法使用 jstack, 不知道为什么, 在linux kernal2.4的版本上, 我连接的上, 但是出不了结果。 因为我们是个每天都开发的在线系统, 如果不能看jstack是痛苦的事情, 虽然kill -3 能使用, 但是, 比较郁闷, 老有程序员把输出控制台文件重复使用, 有的系统, 我就看不了控制台输出。 |
|
返回顶楼 | |
发表时间:2008-11-06
3G的cache 问题就在这里了.
不如考虑改小点看看效果. |
|
返回顶楼 | |
发表时间:2008-11-07
EBA Real-time jvm3.0
|
|
返回顶楼 | |
发表时间:2008-11-07
starfeng 写道 helloboy9527 写道 只是最不爽的一个事情就是,为何GC一定要暂停整个应用程序?我宁愿GC可以耗多点CPU,他完整地占着我的一个CPU来做GC也可以,那另外3G个CPU还是可以处理的。我相信如果是用C++来改写这个程序,应该是完全不需要停的。
1) 分开...至少2jvm, cache的做cache, 应用的做应用, 省得相互影响. 2) 分开后, 对cache处理做进一步代码优化(如果还是慢的话). cache方案有很多,opensource产品也多, 不过, 你最好结合你的业务特点, 依据变的程度, 不同jvm处理不同cache. 触发gc的原因是堆不够用, gc过程耗时长的原因是堆过大(另外,对象引用的判断也耗时) 很明显,在你的这个应用中,靠调参去减少堆或增加的堆的大小是没用的.唯一的办法是,分开处理. 业务这一块,堆小一点, gc速度快, 就算经常gc,也没问题. cache这一块, 堆大一点, 很难很难触发一次gc, 也没问题 这个可能也是个办法,只是觉得不爽而已。为了迁就JVM的弱点,要将业务这样设计。为何JVM自身不能处理大容量的cache,还要用其他如memcached之类的东西?我觉得JVM还有很大的改进空间。期待在JDK7.0中给我惊喜。 |
|
返回顶楼 | |
发表时间:2008-11-07
改变java程序员对gc的完全依赖才是釜底抽薪的办法。
|
|
返回顶楼 | |
发表时间:2008-11-07
sdh5724 写道 CostaR 写道 调整gc参数显然治标不治本,治本的方法前面的大侠们已经说了。
我提供一下我的jvm参数,仅供参考。我的服务器是8G内存,两个四核cpu,PE2950,64位系统 两个JVM,每个JVM的参数如下: -server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Djava.awt.headless=true -XX:+DisableExplicitGC 这个参数的效果对我的应用比较好 修改下比较好: -XX:PermSize=128m 建议改成最大128M,避免没有使用。 -XX:ParallelGCThreads=4 改成跟你的CPU CORE 数量一致, 我记得缺省就是CPU的数量, 具体可以查询下MANUAL。 另外, 对于特殊的应用, 比如楼主的应用, 需要你调整你的老生代区域的大小。 确定的方法如下: 楼主你用命令 jstat -gctuil pid 1000 1000 看几分钟 看下, 老生代在最小的时候, 一般是FULL GC过后的几秒, 你可以看到老生代区域使用的百分比。 比如是 50%,如果, 老生代一直处于70%的以上的水平, 那么需要把老生代调大, 另外, 我建议你, 把Full GC的收集比例调到, 默认值是70%, 对于你的应用, 我建议你调制到80%。 然后, 你用jmap看下, 老生代总共占用了多少内存。 一般来说, 你需要把老生代的内存调节到一个合适你的大小。 建议不要超过70%的使用量就可以了。 这样就能腾出大量的内存给新生代。 这个怎么设置你看下资料, 不然, 你无法自己确定作出微小调整。 这个做法只能尽量避免FULL GC。 这个参数配置方法比较痛苦的是无法使用 jstack, 不知道为什么, 在linux kernal2.4的版本上, 我连接的上, 但是出不了结果。 因为我们是个每天都开发的在线系统, 如果不能看jstack是痛苦的事情, 虽然kill -3 能使用, 但是, 比较郁闷, 老有程序员把输出控制台文件重复使用, 有的系统, 我就看不了控制台输出。 将新生代调大,可以使得minor GC的次数会减少,但每次minor GC的时间反而是增得更大了,根据我的经验,如果新生代为1.5G左右,minor GC已经需要用到快0.3秒了。而minor GC同样是stop-the-whole-world,这样客观上还是不解决问题。 我需要的是一种GC算法,可以在多核的情况下,在较大内存(10多G)的情况下,不管是minor GC,或者是Full GC,均不要stop-the-whold-world,或者停顿非常短的时间(0.1秒以下)。他的CPU可以耗多一点,完整耗掉一个CPU也可以。目前查了几天的资料,看来现在是没有的,期待SUN以后给我们惊喜。 |
|
返回顶楼 | |