【发布时间】:2019-11-11 15:10:10
【问题描述】:
代码读取 CSV 文件的行,例如:
Stream<String> strings = Files.lines(Paths.get(filePath))
然后它映射映射器中的每一行:
List<String> tokens = line.split(",");
return new UserModel(tokens.get(0), tokens.get(1), tokens.get(2), tokens.get(3));
最后收集起来:
Set<UserModel> current = currentStream.collect(toSet())
文件大小约为 500MB 我已经使用 jconsole 连接到服务器,发现堆大小在处理时从 200MB 增长到 1.8GB。
我不明白这个 x3 内存使用量是从哪里来的 - 我预计会出现 500MB 左右的峰值?
我的第一印象是因为没有节流,垃圾收集器根本没有足够的时间进行清理。 但是我尝试使用番石榴速率限制器让垃圾收集器有时间完成它的工作,但结果是一样的。
【问题讨论】:
-
这不是反序列化。
-
为什么要将整个文件读入内存呢?一次处理一行。
-
@user207421 返回
Stream<String>的方法不是将整个文件读入内存。 -
@user207421 根据 google:在计算机科学中,在数据存储的上下文中,序列化是将数据结构或对象状态转换为可以存储或传输并在以后重建的格式的过程。
-
如果您希望减少内存使用量,请参阅my Answer 到类似的问题,其中我展示了使用Apache Commons CSV 库使用
BufferedReader逐步读取文件而不是加载一次完整的文件。通过不读取整个文件,您将节省一半的内存。但是,无论您如何阅读,对象集合总是比答案中描述的 CSV 文件的纯文本占用更多的八位字节。
标签: java garbage-collection jvm file-processing