简体   繁体   English

Tomcat逐渐耗尽内存,部署了WebSocket应用程序

[英]Tomcat gradually running out of memory with WebSocket apps deployed

I have Tomcat 8.5.9 running on an AWS box with 10 different WebSocket apps deployed that each basically act as a message broker. 我在一个AWS盒子上运行Tomcat 8.5.9,部署了10个不同的WebSocket应用程序,每个应用程序基本上都充当了消息代理。 The https connector is using the Http11NioProtocol. https连接器正在使用Http11NioProtocol。 The only parameter I have set is the maxThreads=200 along with the certificate info. 我设置的唯一参数是maxThreads = 200以及证书信息。

The request volume is not very high. 请求量不是很高。 It has been running since Monday morning, and here is what the manager status says: 它从周一早上开始运行,这是经理状态所说的:

Max threads: 200 最大线程数:200
Current thread count: 38 当前线程数:38
Current thread busy: 0 当前线程忙:0
Keep alive sockets count: 1 保持活插座数:1
Max processing time: 234 ms 最长处理时间:234毫秒
Processing time: 17.254 s 处理时间:17.254秒
Request count: 33351 申请人数:33351
Error count: 325 错误数:325
Bytes received: 0.00 MB 收到的字节数:0.00 MB
Bytes sent: 34.07 MB 发送的字节数:34.07 MB

After a few days, I notice the memory usage continue to grow. 几天后,我注意到内存使用量继续增长。 I have to restart Tomcat services about every two weeks or so to prevent getting an OutOfMemoryException. 我必须每两周左右重启一次Tomcat服务,以防止出现OutOfMemoryException。

I have been taking heap dumps and analyzing using the Eclipse MAT, which always points to the WsFrameServer class as being the problem suspect. 我一直在使用Eclipse MAT进行堆转储和分析,它始终指向WsFrameServer类是可疑的问题。 The most recent dump displays the following: 最新的转储显示以下内容:

5,146 instances of "org.apache.tomcat.websocket.server.WsFrameServer", 5,146个“org.apache.tomcat.websocket.server.WsFrameServer”实例,
loaded by "java.net.URLClassLoader @ 0x6c0047c28" occupy 1,383,143,200 由“java.net.URLClassLoader @ 0x6c0047c28”加载占用1,383,143,200
(73.13%) bytes. (73.13%)字节。 These instances are referenced from one instance of 这些实例是从一个实例引用的
"java.util.concurrent.ConcurrentHashMap$Node[]" “java.util.concurrent.ConcurrentHashMap中的$节点[]”

The Dominator Tree is currently has 106,000 entries, most of which are the WsFrameServer class. Dominator Tree目前有106,000个条目,其中大部分是WsFrameServer类。

Am I doing something wrong or is this "normal"? 我做错了什么还是这个“正常”? Are there any specific settings either on Tomcat or on the Connector that I should be setting to prevent this from happening? Tomcat或连接器上是否有任何特定设置我应该设置以防止这种情况发生?

Thanks in advance. 提前致谢。

EDIT: I'm not sure if this is helpful, but here is what the VisualVM monitor looks like: 编辑:我不确定这是否有用,但这是VisualVM监视器的样子:

VisualVM监视器

Hard to be certain without more detail but this is probably related to your session retention. 没有更多细节很难确定,但这可能与您的会话保留有关。 What I think is happening is that the WsFrameServer which extends WsFrameBase is added into the session. 我认为正在发生的是, WsFrameServer延伸WsFrameBase 被添加到会话中。
If you have an unlimited session retention policy then you will eventually run out of memory. 如果您拥有无限制的会话保留策略,那么您最终将耗尽内存。

Try setting a non-0 sessionTimeout 尝试设置非0 sessionTimeout

Code is missing from your question. 您的问题中缺少代码。 (especially how you manage websocket connection) (尤其是如何管理websocket连接)

Did you use tomcat in async mode with a list of connection somewhere? 您是否在异步模式下使用tomcat和某个连接列表?

You don't forget to bind close AND error event to a code that remove the faulty connection from the list ? 您不要忘记将关闭AND错误事件绑定到从列表中删除错误连接的代码?

As we all known, Java GC is lazy. 众所周知,Java GC是懒惰的。 Its memory will continue to grow until it can't have any more memory, then a GC will be triggered to collect garbage. 它的内存将继续增长,直到它无法再有内存,然后会触发GC来收集垃圾。

From the screenshot of your VisualVM, we can see the memory usage is relative normal: more memory used as time goes, memory usage dropped after GC. 从VisualVM的屏幕截图中,我们可以看到内存使用情况相对正常:随着时间的推移,内存使用量增加,GC后内存使用率下降。

So I wonder whether your app will really crash because OOM. 所以我想知道你的应用程序是否真的会崩溃,因为OOM。 You may try it in your test environment, and get the OOM JVM dump to analyse, which is more useful. 您可以在测试环境中尝试它,并获取OOM JVM转储以进行分析,这更有用。

By the way, I suggest VisualVM over MAT, because MAT will include some unreachable objects as GC root. 顺便说一句,我建议VisualVM over MAT,因为MAT将包含一些无法访问的对象作为GC根。 It will make the memory analysis very inefficient and give different result as other tools, which I met in one of our projects. 它将使内存分析效率非常低,并且与我在其中一个项目中遇到的其他工具一样给出不同的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM