java - Files.lines 的高内存使用率
问题描述
我在 SO 上发现了一些其他问题,这些问题与我需要的很接近,但我无法弄清楚。我正在逐行读取文本文件并出现内存不足错误。这是代码:
System.out.println("Total memory before read: " + Runtime.getRuntime().totalMemory()/1000000 + "MB");
String wp_posts = new String();
try(Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)){
wp_posts = stream
.filter(line -> line.startsWith("INSERT INTO `wp_posts`"))
.collect(StringBuilder::new, StringBuilder::append,
StringBuilder::append)
.toString();
} catch (Exception e1) {
System.out.println(e1.getMessage());
e1.printStackTrace();
}
try {
System.out.println("wp_posts Mega bytes: " + wp_posts.getBytes("UTF-8").length/1000000);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("Total memory after read: " + Runtime.getRuntime().totalMemory()/1000000 + "MB");
输出类似于(在内存更多的环境中运行时):
Total memory before read: 255MB
wp_posts Mega bytes: 18
Total memory after read: 1035MB
请注意,在我的生产环境中,我无法增加内存堆。
我已经尝试显式关闭流,执行 gc,并将流置于并行模式(消耗更多内存)。
我的问题是:这是预期的内存使用量吗?有没有办法使用更少的内存?
解决方案
你的问题在collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
. 当您将 smth 添加到StringBuilder
并且它没有足够的内部数组时,它会将其加倍并从前一个数组中复制一部分。
执行new StringBuilder(int size)
预定义内部数组的大小。
第二个问题,是你有一个大文件,但结果你把它放到了StringBuilder
. 这对我来说很奇怪。实际上,这与将整个文件读入 aString
而不使用Stream
.
推荐阅读
- r - readLines function with new version of R
- django - Django 测试卡在迁移/权限上
- jquery - jquery覆盖我的css颜色
- permissions - 哪些是网站的正确权限
- python - 通过 ssh 执行 pyqt 文件
- path - 设置cygwin
- python - 如何在数据库的一列中获取和存储 2 个值?Python Flask SQLAlchemy
- html - 如何将一个div放在另一个div之上
- python - Python 脚本比运行另一个 Python 脚本 ffmpeg2vmaf
- f# - FSharp - 基于数组的匹配和返回记录的意外行为