处理上传的日志文件时服务内存飙升,几百兆的文件直接把堆打满。日志里能对上时间点,这种反而好排。
一次性把整个文件读进字节数组,内存占用等于文件大小,并发几个请求就撑爆。这一点先确认清楚,后面就不用反复试。
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
lines.forEach(this::handle);
}
// 或
BufferedReader br = Files.newBufferedReader(path);
围绕「Java 大文件读取」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
别只看报错的最后一行,往上看几行,真正的起因通常在上面。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。改完隔一天再看一次,当场正常不代表能稳住。
处理上按这个顺序:改为流式按行读取;处理完及时释放引用;限制单次上传大小。
结果对不对很好判断,处理同样的大文件时内存曲线平稳,任务能完整跑完。