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=1122461KB,commited=728301KB,任务管理器显示used=534MB
运行一周后: total=1137792KB,commited=749376KB,但任务管理器显示used=8GB >
为什么使用/保留的内存这么高?
战斗记录器没有显示任何问题,GC运行良好。我尝试将 Oracle Java 8 更新到 OpenJDK 11,将 Spring Boot 更新到更新版本,没有任何帮助。内存消耗增长似乎是线性的。
【问题讨论】:
您为 cache2kCache
条目设置了哪个过期时间?如果您的条目永不过期,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.walk
用 try-with-resources
括起来。
谢谢Petr Janeček
附言服务运行一周后,内存消耗稳定
【讨论】:
不错。这实际上是一个普遍的问题。请随意在您的答案中打勾,因为它是正确的。如果内存使用量/打开的文件数现在稳定,请在一周内告诉我!以上是关于Java 内存消耗很高并且还在增长的主要内容,如果未能解决你的问题,请参考以下文章
为啥在安装Visual Studio 2005之后,开机时"SVCHOST.EXE"进程占用CPU很高?且内存消耗将近100MB!?