【发布时间】: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 更新到更新版本,没有任何帮助。内存消耗增长似乎是线性的。
【问题讨论】:
-
您为 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。非常感谢。