【问题标题】:I am unable to process 5GB text file while getting this error?收到此错误时,我无法处理 5GB 文本文件?
【发布时间】:2014-06-12 04:17:37
【问题描述】:

我正在使用 StringBuilder,读取文件的每条推文并在将其过滤到另一个文件后将其写入。我还在每个循环结束时刷新我的 StringBuilder。我在 2012 年中期使用 8GB RAM mac 视网膜。

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2367)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:535)
    at java.lang.StringBuffer.append(StringBuffer.java:322)
    at java.io.BufferedReader.readLine(BufferedReader.java:363)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at Parser.main(Parser.java:52)

【问题讨论】:

  • 发布代码。看起来你真的没有刷新你的StringBuffer。对于 5 GB,您可能暂时需要三倍的容量:将近 5 GB 的缓冲区可以调整为 10 GB,因此它是 15 GB(假设增长因子为 2)。
  • 检查此线程以分配更多内存stackoverflow.com/questions/2610194/…
  • 代码已经贴出来了。
  • 您将内容存储在内存中的 LinkedHashSet 中,而无需从中删除任何内容。这可能就是内存问题的来源。
  • 好的,那你有什么建议呢?我不认为这是问题所在,我正在尝试使用文档中的基本文件阅读器代码,甚至似乎不适用于 5gb 文件。

标签: java


【解决方案1】:

从程序的结构中,我们可以得出结论,内存占用要么是一个在循环的每次迭代中变大的对象(案例 1),要么是一个在单次迭代中变大的对象(案例 2)。

当 BufferedReader 尝试调整其内部字符缓冲区的大小以容纳一行输入时,堆栈跟踪指示内存分配失败。故障时这条线有多长?您可以通过在调试器中运行程序来找出答案,在 OutOfMemoryError 上有一个异常断点,并检查保存无法分配的数组大小的变量。如果不是很大,我们可以排除情况2。

案例 1 最可能的嫌疑人是 LinkedHashSet 存储输出中所有推文的 tweet_f。尝试估计它的大小(粗略估计可以用 ln.size() * (50 + 2 * 平均字符串长度 in chars),并确保你有足够的内存来保存它。

如果失败,我会使用繁重的工具,即进行堆转储,将其加载到 VisualVM 或商业分析器等分析工具中,让该工具识别大对象以及对这些对象的哪些引用阻止他们的垃圾收集。

【讨论】:

  • 1.是否有适用于 Mac 的 VisualVM? 2. 我没有在 LinkedHashMap 中存储所有推文,它只存储与过滤器匹配的推文,如您所见,它在 if 循环中执行 .add(blah)。更不用说这段代码了,我正在运行标准的 BufferedFile 阅读器 hello world 示例,读取相同的文件并打印出这些行。即使这样也失败了。
  • 1.作为 Oracle JDK 的一部分,我希望 JVisualVM 也可以在 Mac 上使用。 2. 你有没有按照我的建议来检查行长是否合理?
【解决方案2】:

听起来你有内存泄漏。很难在没有源代码的情况下为您提供具体的代码建议,但是即使在刷新 StringBuilder 之后,您也可能有一些对您的 StringBuilder 的引用? VisualVM 是一个很好的免费工具,可用于跟踪运行时发生此类问题的位置。这篇博文介绍了如何做到这一点:http://rejeev.blogspot.com/2009/04/analyzing-memory-leak-in-java.html

【讨论】:

  • 我尝试使用 -Xmx20g 分配 20G 但仍然在线程“main”java.lang.OutOfMemoryError 中显示异常:请求的数组大小超过 VM 限制
猜你喜欢
  • 1970-01-01
  • 2019-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 2018-10-24
  • 1970-01-01
相关资源
最近更新 更多