Java 1.8在Tomcat 6和Tomcat 8中的内存分配行为

14

相关问题:从Java 6 + Tomcat 6升级到Java 8 + Tomcat 8时的垃圾回收器使用情况

我有一组用Java 8编译的Web应用程序。如果我在Tomcat 8中运行它们,就会出现很多次小GC集合和随机内存分配。在Tomcat 6中,内存分配更为线性和稳定(两种情况下都是空闲的,没有流量)。

Tomcat 8 Eden Space:

enter image description here

enter image description here

Tomcat 6 Eden Space:

enter image description here

enter image description here

您知道为什么会发生这种情况吗?

编辑1:

这些是使用jdk 1.8和Tomcat 8的生产环境数据。由于GC循环,CPU几乎总是非常高。对此有什么评论吗?

enter image description here enter image description here

编辑2:

这是一个堆转储分析(1.8 GB 转储):

输入图像描述


1
@GilianJoosen,每个GC循环都需要CPU(请参见CPU使用情况图像),内存泄漏可能会导致连续垃圾收集,占用100%的CPU时间和一个无法使用的服务器。 - Fran Montero
1
在Tomcat 6和Tomcat 8之间有2个主要版本,答案可能是“因为他们改变了东西”。如果您有流量,并且Tomcat不只是空闲状态(因为这才是真正重要的),会发生什么?您的内存是否不足?您的性能是否随着Tomcat 8而降低? - Kayaman
1
@Kayaman 每分钟使用 5 个 GC 循环,占用 20% 的 CPU 时间,与空闲状态下的 0 个 GC 循环和几乎 0% 的 CPU 占用相比,对我来说是一种性能下降。我正在进行 Jmeter 测试,以查看在更高负载下会发生什么。 - Fran Montero
1
好的,我明白你的意思 @Kayaman。当我有高负载下的Jmeter结果时,我会更新我的问题 ;) - Fran Montero
最明显的下一步是分别对您的类和Tomcat的类进行剖析,以查看产生了什么垃圾,然后找出是什么产生了这些垃圾。 - Kayaman
显示剩余5条评论
2个回答

2

这是伊甸空间,而不是终身聘用的空间。所以,这单独就是好消息。

但是,似乎在年轻代GC之后,tomcat8立即分配了某些内存。它可能是一种“气球”技术吗?(分配一个大的弱引用缓冲区以便在内存压力下“紧缩”以确保一些空间)。它也可能隐藏在NIO连接器中,在'oomParachute'参数中(默认为1MB,但是每个httpprocessor线程都是如此吗?如果您有200个最小线程,那将匹配看到的200MB)。

我只建议您可以深入研究changelog,找到新事物或更改,您可能认为它们实现了像这样的浪费机制。

另外:您应该在jdk8中运行tomcat6,以查看是否真的是tomcat8的问题。伊甸空间可能会变得更大,以防G1GC过于激进,觉得自己必须在使用仅200MB时执行GC。


感谢您的回答。 正如我在帖子中所说,我在Tomcat 6和Tomcat 8上运行相同的应用程序。 "异常"行为仅在Tomcat 8中发生。 我使用Javosize找到了问题,请查看我的答案。 - Fran Montero

1
感谢大家抽出时间阅读。 最终,问题是Tomcat 8.0_23中的一个bug。 使用Javosize,我看到一个线程几乎占用了所有CPU时间:

enter image description here

我在互联网上找到了这个Tomcat AJP Bug
此外,我已经测试了Tomcat 8.0_32,并且Poller线程甚至不存在,所以问题得到解决。
问候。

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