java - JVM Garbage Collector 在运行数小时后突然消耗 100% CPU

标签 java clojure garbage-collection jvm java-websocket

我的 Clojure 应用程序出现了一个奇怪的问题。

我正在使用 http-kit 编写基于 websocket 的聊天应用程序。

客户端使用 React 作为单页应用程序呈现,当他们导航到主页(登录后)时,他们做的第一件事就是创建一个 websocket 来接收实时更新和任何聊天消息等内容。您可以在此处查看该站点:www.csgoteamfinder.com

我遇到的问题是经过一段不确定的时间后,可能是重启后 30 分钟甚至 48 小时,运行聊天服务器的 JVM 突然开始占用所有 CPU。当我用 NR(New Relic)检查它时,我可以看到所有时间都被垃圾收集器使用了——在这个阶段我不知道它在做什么。

我已经截了一些截图,你可以看到效果。

New Relic showing memory usage over a 7 day period

More New Relic statistics

您可以看到许多尖峰,这些尖峰对应于垃圾收集器导致的 CPU 使用率大幅增加。为了释放 CPU,我通常必须重新启动 JVM,我一直依赖于在我的 slack 帐户中收到来自 NR 的 CPU 警报,以确保我快速跳转到这些......但我真的需要找到问题的根源问题。

我最初的想法是,当客户端在他们结束时关闭它时,我可能持有套接字引用,但事实并非如此。我一直在定期查看套接字数量,它相当稳定。

有从哪里开始的想法吗?

亲切的问候,杰森。

最佳答案

很难想象是什么导致了这样的问题。但起初我会做的是在崩溃时进行堆转储。这可以通过 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path_to_your_heap_dump> 启用JVM 参数。 作为一般做法,不要将堆大小增加到超过服务器计算机上可用物理内存的大小。在极少数情况下,JVM 无法转储堆空间,因为进程已死;在这种情况下,您可以使用 gcore (如果您使用的是 Linux,则不确定是否使用 Windows)。

获取堆转储后,使用 mat 对其进行分析,我已经调试了这样的应用程序,这完美地解决了任何与内存相关的问题。 Mat允许您深入剖析堆转储,因此如果您分配的堆空间不是非常小,您一定会找到内存问题的原因。

关于java - JVM Garbage Collector 在运行数小时后突然消耗 100% CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35262175/

相关文章:

java - 尝试将 AndEngine 添加到我的示例项目时出错

json - 如何选择Clojure JSON库

clojure - 为什么环在这个响应中给我错误?

c# - 如何处理我们没有引用的一次性元素?

java - Activity 调用 finish() 时通知 pendingIntent contentIntent 失败

java - 向多个表添加数据行时实现 AsyncTask

Clojure 静态类型,第 2 部分

java - Java 中没有变量引用的新实例会被垃圾收集吗?

C# WebClient - 下载文件后 LOH 大幅增加

java - Sun 的 HTTP-Server 直接读取数据