Java GC和Java堆空间使用的正常行为是什么?

时间:2013-10-02 11:31:25

标签: java jboss garbage-collection

我不确定是否有一个通用的答案,但我想知道正常的Java GC模式和Java堆空间使用情况是什么样的。我正在使用JMeter测试我的Java 1.6应用程序。我正在收集JMX GC日志并使用JMeter JMX GC和Memory插件扩展来绘制它们。 GC模式看起来相当稳定,大多数GC操作为30-40ms,偶尔为90ms。内存消耗采用锯齿形式。 JHS使用量持续增长,例如到3GB和每40分钟,内存使用量会自由下降到1GB左右。然而,最大 - 最小三角洲增长,因此锯齿高度不断增长。它是否每40分钟完成一次GC?

3 个答案:

答案 0 :(得分:1)

一般来说,大部分描述都是GC的工作原理。但是,您的具体观察结果,特别是数字,都不适用于一般情况。

首先,每个JVM都有一个或多个GC实现,您可以选择使用哪个。以大多数应用的方式为例,即SUN JVM(我喜欢这样称呼它)和公共服务器GC模式为例。

首先,记忆分为4个区域。

  • 年轻一代,拥有所有最近创建的对象。当这一代人满员时,GC通过停止你的程序工作来执行一个世界各地的集合,执行黑灰白算法并获取obselete对象并删除它们。所以这是你的30-40毫秒。

  • 如果一个物体在年轻人的某一轮GC中幸存下来,它将被转移到交换代。交换生成将对象保持到另一个GC,然后将它们移动到旧一代。有2个交换代,它可以做一个双缓冲的事情,以促进年轻人更快地工作。如果年轻的gen转储交换gen并发现swap gen大部分已满,那么GC会在swap gen上发生,并可能将幸存的对象移动到old gen。这很可能使你的90ms,虽然我不是100%肯定交换gen如何工作。如果我错了,有人会纠正我。

  • 交换gen幸存的所有对象都将被移动到旧一代。老一代只有GC编辑,直到它大部分都满了。在你的情况下,每40分钟。

  • 还有另一个“永久gen”用于加载jar目标字节代码和资源。

可以通过JVM参数调整所有区域大小。

您可以尝试使用VisualVM,它可以让您动态了解它的工作原理。

P.S。并非所有JVM / GC都以相同的方式工作。如果您使用G1收集器或JRocket,它可能会略有不同,但总体思路仍然存在。

答案 1 :(得分:0)

是的,很有可能。而不是猜测你可以使用jstat来监控您的GC。

我建议您使用内存分析器,以确保您无法做任何简单的事情来改善您生产的垃圾量。

顺便说一句,如果你增加年轻一代的体型,你可以减少垃圾进入终身空间的数量,从而减少完整收藏的频率。如果你对它进行足够的调整,你可能会发现每天不到一个完整的集合。

对于一个更极端的情况,我已经将交易系统调整为每天少于一个集合(次要或主要)

答案 2 :(得分:0)

Java GC根据对象的生成工作。有年轻,任期和世代相传。在您的情况下似乎:每30-40毫秒GC流程只有年轻一代(并将幸存的物品转移到生产期)。并且每40分钟执行一次完全收集(它会导致世界停止)。注意:它不是按时间发生,而是按使用内存的百分比发生。

有几个JVM选项,允许您选择生成的大小,GC的类型(GC有几种算法,默认使用java 1.6 Serial GC,例如 -XX:-UseConcMarkSweepGC ),GC工作的参数。

你最好试着找到关于世代和不同类型的GC的好文章(算法真的不同,其中一些可以避免停止世界停顿!)