Java Tomcat许多NioBlockingSelector$BlockPoller实例填满了内存

Java Tomcat许多NioBlockingSelector$BlockPoller实例填满了内存,java,linux,tomcat,nio,connector,Java,Linux,Tomcat,Nio,Connector,在Java 7上使用Tomcat 7.0.42的应用程序(Java(TM)SE运行时环境(build 1.7.0_51-b13)Java HotSpot(TM)64位服务器VM(build 24.51-b03,混合模式))中,我遇到了一个反复出现的问题 问题是,没有任何明显的原因,而且显然是随机的(我认为显然不是),Java堆的填充率高达75%以上,一个完整的gargbage集合被激活 问题是,在FullGC之后,没有任何内存被释放,因此,FullGC再次启动。这会持续重复,因此CPU只忙于执行

在Java 7上使用Tomcat 7.0.42的应用程序(Java(TM)SE运行时环境(build 1.7.0_51-b13)Java HotSpot(TM)64位服务器VM(build 24.51-b03,混合模式))中,我遇到了一个反复出现的问题

问题是,没有任何明显的原因,而且显然是随机的(我认为显然不是),Java堆的填充率高达75%以上,一个完整的gargbage集合被激活

问题是,在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线程转储,这是这个问题出现的一次,我不能在这里发布,以避免角色限制。如果有人想看,请询问,我会分享

我现在唯一的解决方案是杀死TomcatJava进程并再次启动服务器

这可能是什么原因

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

我正在Linux(
Linux版本3.10.0-123.9.2.el7.x86)上运行Java 7(build 1.7.0_51-b13)上的Tomcat 7.0.42(builder@kbuilder.dev.centos.org)(gcc版本4.8.2 20140120(Red Hat 4.8.2-16)(gcc))#1 SMP周二10月28日18:05:26 UTC 2014


我也有JBoss Infinispan缓存和Apollo MQ消息服务的实例,但我不认为这两者都是罪魁祸首。

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

您的log4j级别可能太低(例如跟踪)

这导致:

  • 争论
  • 内存分配
  • 糟糕的表现
由于争用,内存保留的时间更长

尝试将log4j级别设置为警告


这可能无法纠正您的所有问题,但会有所帮助。

出现问题时,请提供应用程序的线程转储。@benw,谢谢您的回复!我这里有一个链接,感谢您的回复!我也注意到了这一点,但我不知道通过log4j的块和争用是在之后还是之前发生的,因为由于GC占用了大部分CP Utime,没有线程可以执行它们的代码,所以,我认为,当持有锁的线程无法前进并释放它们时,事情会被锁定是可以预料的。另一件事是,这种情况发生得非常快,然后,在相同(或更多)的HTTP负载量(以及更多的日志记录)下,不会再次发生。我肯定会调整log4j的性能,但我怀疑这是真正的原因。。。