在JVM中增加驻留内存大小是否表明内存泄漏?

时间:2011-10-04 21:05:05

标签: java memory-management jboss garbage-collection

我正在使用以下命令行选项启动JBoss 4.2服务器实例:

-Xms8192m -Xmx8192m -XX:+ DisableExplicitGC -XX:MaxPermSize = 512m

我没有收到OutOfMemoryException,但是如果因为他们的引用死亡,那么我不希望内存使用量增加。常驻内存使用量(以顶部测量)从~4.2G开始,并在接下来的几天内持续增加到一周,直到达到8.4G。我仍然没有收到异常。我担心的是,在重要活动期间(JBoss Messaging处理> 10k mssgs / sec),每隔6-10秒就会出现约100-700ms的处理滞后。这似乎与驻留内存使用量的增加有关。这是在具有2个四核处理器和32G内存的机器上进行的。

我将打开其他命令行参数:

-verbosegc -XX:+ PrintGCDetails

但是,我想知道这似乎是垃圾收集问题还是内存泄漏?我试图追踪潜在的内存泄漏几周,并找到了我认为肯定会修复它的XML处理的东西,但这是一个死胡同。无论是否存在泄漏,常驻内存使用量是否会升高以满足Xmx的值(特别是在禁用显式GC的情况下)?是否有一些其他垃圾收集参数可能有帮助,如果它确实不是泄漏(如修改垃圾收集器类型,幸存者比率或暂停目标)?

我知道100-700ms的延迟似乎并不多,但它有可能在这个应用程序中产生显着的差异。提前感谢您提供的任何帮助/建议。

3 个答案:

答案 0 :(得分:1)

Java中“泄漏”的定义与C / C ++中“泄漏”的定义大不相同。在C / C ++中,当您mallocnew存储时,您会收到“泄漏”,而后来永远不会freedelete

但是在Java中,当然,你永远不会删除任何内容,而是将其留给GC查找不再引用的内容并将其释放。

然而,可能会发生的是,某些复杂的数据结构会被构建,然后再构建一些,然后构建更多,有时是无意的。

最明显的情况是类似于StringBuffer,用于累积日志信息而不会写入/清空。但是你也可以在你的应用程序中有一个(故意)长寿命的结构,你碰巧“停放”了一些(据说是)短命的对象,但是却没有null指向“短命”的指针完成它之后的对象,使它有效地变成不朽的。其中一些是显而易见的,有些需要大量的调查来弄明白。

但是在大​​型服务器中,即使没有这样的泄漏,你也会在一段时间内相当稳定地积累“东西”。例如,如果调用给定的应用程序,它可能会导致创建一些对象(或者仅加载类,它们间接创建的对象),并且这些对象可能“挂起”直到下次调用应用程序。像网页缓存这样的东西填满了。如果使用类似JSP的东西,那么将创建对象并将其“缓存”以供以后使用。

但是这种“东西”的积累应该观察到渐近的行为,随着时间的推移慢慢接近一些稳态值。如果它在稳定状态下继续向上,那么你可能会有“泄漏”。

重新启动GC行为,在繁忙的服务器上每隔几秒钟运行一次GC并不罕见。您可以使用调整参数来尝试“平衡”不同的GC“层”,但这样做有点黑色。并且通常在服务器上的GC性能不佳只是因为GC实现没有为服务器设计良好 - 繁忙的服务器上的GC需要能够以大部分并发的方式运行,并且大多数GC实现不会做得很好。

答案 1 :(得分:0)

  

我没有收到OutOfMemoryException,但我不希望这样   如果将事物作为GC引用,则内存使用量会增加   死。

这不一定正确。对象可以放在堆的tenure内存中。如果对象被引用的时间超过“短时间”,则会发生这种情况。一旦进入任期,它通常不会被垃圾收集到达最大堆。因为堆内存使用量没有减少并不意味着你有泄漏。

正常的内存配置文件(使用的堆与时间的关系)看起来像一个锯齿 - 内存使用缓慢增加,直到某个阈值(通常是最大堆),然后由于GC而减少,然后再次缓慢增加。

答案 2 :(得分:0)

我要添加的只是尝试将探查器连接到您的应用程序,并查看内存使用情况的行为。我已经成功地分析了Weblogic A.S.的实例。同时使用jProfiler和YourKit,虽然我没有尝试过JBoss,但应该相当容易。

您是否可以在测试环境中复制此行为(因为分析器在性能上有点沉重,只有在您绝望时才在生产环境中执行)?如果这样做,您可以看到GC是否仅在达到XMX阈值时被调用(并不意味着任何错误),并且您可以显式调用GC以查看它的行为方式。即使使用GC调用,如果内存不断增加,也可能表示存在问题。

一个体面的探查器可以告诉你哪些对象的数量增长速度更快等等,如果确实有“泄漏”,这可以帮助你极大地帮助你。