Java JVM中驻留内存大小的增加是否表示内存泄漏?

Java JVM中驻留内存大小的增加是否表示内存泄漏?,java,memory-management,jboss,garbage-collection,Java,Memory Management,Jboss,Garbage Collection,我正在使用以下命令行选项启动JBoss 4.2服务器实例: -Xms8192m-Xmx8192m-XX:+DisableExplicitGC-XX:MaxPermSize=512m 我还没有收到OutOfMemoryException,但我不希望内存使用量会随着引用的消失而增加。常驻内存使用量(以top衡量)从~4.2G开始,在接下来的几天到一周内稳步增加,直到达到8.4G。我仍然没有收到例外。我担心的是,在重要活动期间(JBoss消息处理>10k毫秒/秒),每6-10秒会出现约100-700毫

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

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

我还没有收到OutOfMemoryException,但我不希望内存使用量会随着引用的消失而增加。常驻内存使用量(以top衡量)从~4.2G开始,在接下来的几天到一周内稳步增加,直到达到8.4G。我仍然没有收到例外。我担心的是,在重要活动期间(JBoss消息处理>10k毫秒/秒),每6-10秒会出现约100-700毫秒的处理延迟。这似乎也与常驻内存使用率的上升有关。这发生在一台有2个四核处理器和32G内存的机器上

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

-verbosegc-XX:+printgc详细信息

但是,我想知道这是垃圾收集问题还是内存泄漏?几周来,我一直在努力追踪一个潜在的内存泄漏,并发现了一些XML处理的问题,我认为这些问题肯定会解决,但这是一条死胡同。无论是否存在泄漏(尤其是禁用显式GC时),驻留内存使用率是否会爬升以满足Xmx的值?如果确实不是泄漏,是否有其他一些垃圾收集参数可能会有所帮助(例如修改垃圾收集器类型、幸存者比率或暂停目标)

我知道100-700毫秒的延迟看起来并不多,但它有可能在这个应用程序中产生显著的不同。提前感谢您提供的任何帮助/建议。

Java中的“泄漏”定义与C/C++中的“泄漏”定义有很大不同。在C/C++中,当你
malloc
new
一块存储时,你会得到一个“泄漏”,并且以后再也不会
释放它或
删除它

但在Java中,当然,您从不删除任何内容,而是将其留给GC来查找不再引用的内容并将其释放

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

最明显的情况是类似StringBuffer的东西,用于累积日志信息,并且从不写入/清空。但是你也可以在你的应用程序中有一个(有意的)长寿命结构,你碰巧“停放”了一些(假定的)短命对象,但是在你处理完它之后,却不能
null
指向“短命”对象的指针,导致它实际上成为不朽的。这些事情有些是显而易见的,有些需要大量的调查才能弄清楚

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

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

在您的GC行为中,在繁忙的服务器上每隔几秒钟运行一次GC是很正常的。您可以使用调优参数来尝试“平衡”不同的GC“层”,但这样做有点像黑魔法。服务器上的GC性能往往很差,这仅仅是因为GC实现不是为服务器精心设计的——繁忙服务器上的GC需要能够以很大程度上并发的方式运行,而大多数GC实现并不能很好地做到这一点

我没有收到OutOfMemoryException,但我不希望 如果事物被GC作为它们的引用,内存使用会增加 死

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


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

我要添加的唯一一件事是尝试将配置文件连接到应用程序,并查看内存使用情况。我已经用jProfiler和YourKit成功地分析了Weblogic A.S.的实例,虽然我没有用JBoss尝试过,但应该相当容易

您能否在测试环境中复制此行为(因为探查器对性能有很大的影响,所以只有在您感到绝望时才在生产环境中进行)?如果您这样做,您可以看到GC是否仅在达到XMX阈值时才被调用(并不意味着有任何错误),并且您可以显式地调用GC以查看其行为。即使使用GC调用,内存也会不断增加,这可能表明存在问题


一个好的探查器可以告诉你哪些对象的数量增长得更快,如果你真的有“漏洞”的话,这可以极大地帮助你解决问题。

如果你还没有这样做,我建议你用JConsole(或它的后继者)监控Java进程:猜猜,有什么东西(例如缓存)吗使用一堆
SoftReference
s?@palsm4-我还没有这样做。谢谢你的提示,我会查一查的。有吗