【发布时间】:2021-10-11 08:38:36
【问题描述】:
我发现我的一个 spring boot 项目的内存(RAM 消耗)每天都在增加。当我将 jar 文件上传到 AWS 服务器时,它占用了 582 MB 的 RAM(最大分配的 RAM 为 1500 MB),但每天,RAM 增加 50 MB 到 100 MB,5 天后,今天占用了 835 MB .目前该项目有 100-150 个用户,并且正常使用 Rest API。
由于 RAM 的增加,应用程序多次出现以下错误(从日志中发现错误):
Exception in thread "http-nio-3384-ClientPoller" java.lang.OutOfMemoryError: Java heap space
为了解决这个问题,我发现通过使用 JAVA Heap Dump,我可以找到占用内存的对象/类。因此,通过在命令行中使用Jmap,我创建了一个堆转储并将其上传到Heap Hero 和Eclipse Memory Analyzer Tool。在他们两个中,我发现了以下内容:
1. 总浪费内存为:64.69MB (73%)(查看下方截图)
2。其中,Byte [] array 和 LinkedHashmap[] 占用了 34.06MB(查看下面的截图),我在整个项目中从未使用过。我在我的项目中搜索了它,但没有找到。
3。以下 2 个大对象分别占用 32 MB 和 20 MB。
1. Java Static io.netty.buffer.ByteBufUtil.DEFAULT_ALLOCATOR
2. Java Static com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.connectionFinalizerPhantomRefs`
所以我试图找到这个 netty.buffer。在我的项目中,但我没有找到任何与 netty 或 buffer 匹配的东西。
现在我的问题是我怎样才能减少这种内存泄漏或我怎样才能找到确切的内存消耗对象/类/变量以便我可以减少堆大小.
我知道很少有专家会要求提供源代码或类似的东西,但我相信从堆转储中我们可以找到内存泄漏或内存中可用的活动对象 .我正在寻找该选项或任何减少此堆转储的方法!
过去 3 周我一直在处理这个问题。任何帮助,将不胜感激。 谢谢!
【问题讨论】:
-
Something 使用了 Netty IO 框架。您所看到的很可能是缓冲区缓存。除非它失去控制,否则你无能为力。 32MB 没有失控。
-
我会建议一种方法。在下一次回收之后或现在,只对“活动”对象进行一个堆转储。 jmap 有这个选项。一旦您看到 1-2 天后堆使用量上升,请以类似的方式进行另一个转储。继续收集它几天,直到它崩溃。然后比较转储中的对象增长。 MAT可以。如果有泄漏,您应该会看到增长模式。另外请记住,转储“实时”对象是关键。快乐的泄漏狩猎! :)
-
@suv3ndu 谢谢,但上面的图片和解释是活体的。这是我使用“jmap -dump:live,format=b,file=/home/ubuntu/dump 35”的命令,其中 35 是我的进程 ID
-
@KishanSolanki 这些图片来自最终的故障转储吗?如果是这样,对我来说,它们看起来不像是您提到的每天 50-100MB 增长的泄漏对象。这就是我建议这种方法的原因。
标签: java spring-boot out-of-memory heap-dump java-heap