我的应用程序中存在严重的内存泄漏。我已经运行了jmap,它说当前有以下对象不应该存在(并且是泄漏的主要来源):
java.lang.management.MemoryUsage - 3938500 instances, 189048000 bytes
[Ljava.lang.management.MemoryUsage - 787700 instances, 31508000 bytes
com.sun.management.GCInfo - 293850 instances, 22055600 bytes
sun.management.GCInfoCompositeData - 393850 instances, 12603200 bytes
我不直接使用这些对象。然而,它们被垃圾收集器使用。 我用:
Java version: 1.7.0-b147
VM version: Java Hotspot(TM) 64-bit Server VM (build 21.0-b17, mixed mode)
The application is run in Jetty version 7.3.1
我使用当前的Concurrent低暂停垃圾收集器。但是,即使运行吞吐量收集器,我也遇到了同样的问题。
你知道为什么这些物体会留在记忆中吗?你有什么建议吗?
更新:Java 1.7更新1(1.7.0_01-b08,Java Hotspot(TM)64位服务器VM(版本21.1-b02,混合模式))仍会发生内存泄漏。
更新2:内存泄漏是由JConsole引起的。在JConosole启动之前,没有上面提到的类的实例。一旦我使用JConsole连接到应用程序,对象就会开始出现在内存中,并且它们永远保留在那里。关闭JConsole后,对象仍然在内存中,并且它们的数量一直在增长,直到应用程序关闭。
答案 0 :(得分:4)
我还没有真正使用过jmap,但我在应用程序中处理了内存泄漏。
您的应用程序是否内存不足?我建议在应用程序关闭之前进行转储,将以下内容添加到您的vm args
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp
当你的应用程序运行时,它会在tmp下创建一个hprof文件,你可以用来调试这个问题。
如果它没有进入OOM,请尝试分配较低的内存,以便强制执行OOM。
我使用eclipse MAT来分析这些文件。这是非常好的,因为它会立即告诉你泄密的嫌疑人。
答案 1 :(得分:1)
我认为您需要提供有关应用程序的用途以及正在执行的操作的更多详细信息。您是否只是使用jConsole来跟踪此问题?
我使用Visual VM来追踪这些类型的问题。请参阅此link,了解如何将其用于内存泄漏,并将此文件用于Visual VM主page。
答案 2 :(得分:0)
我有同样的问题。我在2个月前做过调查,问题出在JAVA 7_0虚拟机上。在我的场景中,java.lang.management.MemoryUsage对象挂起并且每天增长数百MB。您看到挂起的所有其他对象都由java.lang.management.MemoryUsage对象引用。问题是,这个MemoryUsage对象只在java 7_0及更高版本中挂起,因为这个MemoryUsage类已被添加到JAVA 7中,并且从未在之前的java中。最重要的是,只有在我使用JConsole连接到服务器之后,这个MemoryUsage类才挂在内存中。在JConsole第一次连接之后,它会创建一些MemoryUsage跟踪机制,该机制开始创建MemoryUsage对象。然后使用这些对象在JConsole中绘制漂亮的图形。一切都好。但问题是,JAVA 7是有缺陷的,并且永远不会释放内存。 MemoryUsage对象永远挂在堆上。关闭JConsole并不重要,之后它会继续增长。第一次使用JConsole连接到JAVA 7_0进程时,会产生问题并且没有解决方案。只是不要使用Jconsole或任何其他内存监控工具,或者不使用Java 7.在我的场景中,我注定要失败,因为我必须一直使用Jconsole,而JAVA 6对我来说是没有选择的,因为还有另一个错误,由于锁定对象而导致内存泄漏。我向ORACLE报告了这个错误,但我不知道,如果他们得到它,就知道它并正在解决它。我只是在等待更新版本的java,所以我可以测试它并且每隔几天就停止重新启动我的服务器。
答案 3 :(得分:0)
几年前我向Oracle报告了一个问题,在JDK 7中,当你连接JConsole时会发生内存泄漏。泄漏将永远存在;即使断开JConsole。
泄漏了什么?与垃圾收集器运行原因有关的对象。实际上大多数是字符串(例如"分配失败")。我只发现了这个问题,因为我使用了YourKit,而在YourKit中,你可以分析被标记为垃圾收集的对象。基本上,我的应用程序中的任何东西都没有引用这些对象,但它们也没有被垃圾收集器收集。
大多数堆转储工具会立即从分析中删除垃圾回收对象。因此,YourKit在确定该错误确实存在于JVM中时至关重要。
无法找到我的机票,但我找到了其他机票: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7143760 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7128632