Tomcat许多NioBlockingSelector$ blockpolller实例填充内存



我在Java 7 (Java(TM) SE Runtime Environment (build 1.7.0_51-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode))上使用Tomcat 7.0.42的应用程序遇到了一个反复出现的问题

问题是,没有任何可见的原因,显然是随机的(显然不是,我认为)Java堆填充了超过75%,并激活了一个完整的垃圾收集。

问题是,在FullGC之后,没有任何内存被释放,所以,FullGC重新开始。这个过程不断重复,因此,CPU只忙于执行GC,几乎没有CPU周期给任何其他线程,有效地挂起了所有其他Tomcat线程。

这发生在不超过5或10分钟的时间内。

这似乎与系统负载无关,因为当我没有超过2个线程在运行时也会发生这种情况。

由于Java进程的无响应,即使试图获得堆或堆栈转储也是困难的。

我确实有一次获得了堆直方图,不幸的是,我现在没有完整的直方图(我的错,我没有通知就删除了文件),但我从聊天中保留了这些信息:

1:      48504970     1552159040  org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller$2
2:      48506821     1164163704  java.util.concurrent.ConcurrentLinkedQueue$Node

可以看到,有超过48k个org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller$2实例和相同数量的java.util.concurrent.ConcurrentLinkedQueue$Node实例(这些实例由第一个实例持有)。这几乎可以容纳2.5GB,而我的内存堆是3GB。

我有一个jstack线程转储的时候这个问题出现了,我不能在这里张贴做字符限制。如果有人想看,请问,我会分享的。

我现在唯一的解决方案是终止Tomcat java进程并重新启动服务器。

这可能是什么原因呢?

甚至发生的时间似乎都是随机的。它有时发生在早晨,有时发生在晚上。有一天,它在同一天发生了两次(中间重新启动了Tomcat)。

我在Java 7 (build 1.7.0_51-b13)和Linux (Linux version 3.10.0-123.9.2.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP Tue Oct 28 18:05:26 UTC 2014)上运行Tomcat 7.0.42。

我也有JBoss Infinispan Cache和Apollo MQ消息服务的实例,但我不认为它们是罪魁祸首。

大多数http线程在log4j中被阻塞。

您可能有log4j级别太低(例如trace)

这导致:

    争用
  • 内存分配
  • 坏性能

由于争用,内存被占用的时间更长。

尝试将log4j级别设置为WARN。

最新更新