Java 内存消耗很高并且还在增长

Posted

技术标签:

【中文标题】Java 内存消耗很高并且还在增长【英文标题】:Java memory consuming is high and growing 【发布时间】:2022-01-06 02:55:16 【问题描述】:

我有一个 Spring Boot REST 服务,它每分钟将文件从文件夹移动到 ZIP 存档中,并将存档上传到另一个服务。我的服务使用 Cache2K 和 HSQLDB 保存压缩文件和 zip 名称的映射。另一个应用程序使用该服务来注册创建的文件,然后询问文件所在的 zip 的名称。

服务在 Windows Server 2019 Standard 32GB RAM 上运行,带有启动参数

java -Xms512M -Xmx512M -XX:MaxMetaSpaceSize=128MB -XX:NativeMemoryTracking=detail

jcmd 1234 VM.native_memory的结果

运行 1 分钟后: total=1122461KBcommited=728301KB,任务管理器显示used=534MB

运行一周后: total=1137792KBcommited=749376KB,但任务管理器显示used=8GB >

为什么使用/保留的内存这么高?

战斗记录器没有显示任何问题,GC运行良好。我尝试将 Oracle Java 8 更新到 OpenJDK 11,将 Spring Boot 更新到更新版本,没有任何帮助。内存消耗增长似乎是线性的。

【问题讨论】:

您为 cache2k Cache 条目设置了哪个过期时间?如果您的条目永不过期,Cache 将永远持有对您的条目的引用,因此 GC 将永远不会释放此内存。 缓存项过期10分钟,新文件传入速度20/分钟,每个文件(缓存项)请求3-5分钟。 我不相信有问题。无论如何,最常见的是未关闭的文件或 IO 流。一定要确保你在任何你应该使用的地方都使用了 try-with-resources。一个令人惊讶的地方是像Files.newDirectoryStream()Files.find() 这样的电话。使用docs.microsoft.com/en-us/sysinternals/downloads/… 查看您的进程保存了哪些文件。如果是所有的 zip 文件或任何其他意外,那就是你的泄漏。另外,-XX:NativeMemoryTracking=datail 应该是 detail,你的错字了。 听起来你有内存泄漏 谢谢,“datail”只是那里的打字机。 ProcesExplorer 显示 HandlesCountm 每秒增加一个句柄。真的,我发现Files.newDirectoryStream()Files.walk 在我的代码中没有try-with-resources。代码固定和手柄摆动约 730-750。非常感谢。 【参考方案1】:

如果使用堆外内存,请尝试-XX:MaxDirectMemorySize 参数

【讨论】:

好的,我试试,但是 MaxDirectMemorySize 默认应该等于 Xmx 你为什么这么说?手动条目说:“默认情况下,大小设置为 0,这意味着 JVM 会自动选择 NIO 直接缓冲区分配的大小。”。里面没有提到-Xmx 因为我看到他说他做了文件操作,这是一种直觉【参考方案2】:

问题解决了。

Files.newDirectoryStream()Files.walktry-with-resources 括起来。

谢谢Petr Janeček

附言服务运行一周后,内存消耗稳定

【讨论】:

不错。这实际上是一个普遍的问题。请随意在您的答案中打勾,因为它是正确的。如果内存使用量/打开的文件数现在稳定,请在一周内告诉我!

以上是关于Java 内存消耗很高并且还在增长的主要内容,如果未能解决你的问题,请参考以下文章

在多线程环境中使用 PyCurl 时程序消耗的内存不断增长

为啥在安装Visual Studio 2005之后,开机时"SVCHOST.EXE"进程占用CPU很高?且内存消耗将近100MB!?

xlsxwriter 消耗太多内存并且进程被杀死

TPL 数据流块消耗所有可用内存

Java BufferedImage 内存消耗

怎么查看java程序运行的峰值内存消耗(含虚拟机)和CPU消耗(ms)