Tomcat空闲时的内存使用量增加

5
我在Tomcat上遇到了内存消耗增加的问题。刚开始启动时,一切正常,但是如果有用户登录后,内存使用量就开始在Edem中增长。PermGen不会增长,但是这仍然是异常的。
我的分析显示,线程RMI TCP Connection产生了大量的Object[] char[]和String[]对象。我无法理解出错了什么,也不知道应该从哪里入手。是谁启动了这个线程?它是由postgres连接开启的吗?这是什么问题?jvisualvm profiling
2个回答

5

这是正常的,不是内存泄漏。应用程序管理的线程不断地创建和销毁对象。你看到内存增加是因为JVM垃圾回收器没有急切地回收未使用的内存。这种情况会定期发生(基于先前的统计数据)或者当内存不足时。如果是真正的内存泄漏,你在集合后不会看到伊甸园内存使用量几乎降至零。内存泄漏表现为最低点(GC之后)随着时间的推移而增加。


我同意,但是在本地电脑上,即使没有任何活动,eden也会快速增长;而在生产环境中,tomcat启动失败。 - ekitru
实际上我没有遇到OOM异常,但是在生产环境中,有时候Tomcat会开始使用99%的CPU负载,并且不再响应。 - ekitru
1
当您的生产Tomcat停止响应时,您应该获取线程转储并检查它。根据您使用的JVM不同,您还将获得内存使用情况,这可能会让您排除内存泄漏的可能性。 - Andres Olarte
我刚刚在服务器上遇到了问题,并从中获取了堆转储。但是没有有用的信息=(按大小排序,最大的是char[]和String[]。 - ekitru
我无法发布堆转储,但保留最流行的排序是: HashMap,org.hibernate.persister.entity.SingleTableEntityPersister, org.hibernate.loader.Loader[]通过jvisualvm我能找到什么? - ekitru
显示剩余3条评论

2
您正在观察自己的观察:
JVM收集有关自身的统计信息并将其发送给您。这会消耗内存并使用RMI传输设施。
“Visual VM中的RMI TCP Accept、Attach Listener和Signal Dispatcher是什么?”请参见此处
我也没有看到图像显示的问题。伊甸园基本上总是缓慢增长,因为总是有一些消耗内存的工作。
一旦Eden被收集(在最后约200MB),您可以看到大部分内存完全空闲,只有很少量(约8MB)的对象结束在Survivor空间中,因为可能仍然存在对这些对象的引用。但它们似乎没有离开Survivor,因为OldGen没有增长,底部的直方图显示典型的Survivor对象到达第2级,然后消失。
所有这些看起来对我来说都很正常。

没错,但服务器什么也没做,没有人连接它,在生产环境中会间歇性地失败。 - ekitru
1
请长时间监视您显示的图像,如果有内存泄漏,则会看到OldGen(和/或可能是PermGen)随着时间增长而增加。一旦OldGen已满且Garbage收集器无法释放足够的空间,JVM将出错。还可以参见https://dev59.com/6XRB5IYBdhLWcg3wtZIV,以获取应包含实际问题的堆转储。即使您的服务器处于空闲状态:JVM也有管理任务,例如运行垃圾回收线程,因此始终存在一些活动。 - zapl
我在生产环境中发现了PermGen OOM异常,太糟糕了。=( - ekitru
1
也许可以参考这个链接:https://dev59.com/Q2kw5IYBdhLWcg3wKneb#10248938,或者是这个链接:http://frankkieviet.blogspot.ca/2006/10/classloader-leaks-dreaded-permgen-space.html。 - zapl
谢谢,好文章! 我认为这不是类加载器内存泄漏,因为我们已经尝试过不重新部署,而是通过停止/启动Tomcat来重启。堆显示有70 MB的HashMap和HashMap数组。 - ekitru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接