【问题标题】:GC overhead limit exceed when reading large file读取大文件时超出 GC 开销限制
【发布时间】:2015-06-09 09:32:02
【问题描述】:

我想逐行读取我的 .csv 文件,以免一次将所有内容加载到 RAM 中。我认为这是做到这一点的方法。我还以一种在循环中不声明任何变量的方式编写代码,以使 JVM 免于总是创建新对象和运行垃圾收集器。

但是,我一直遇到此“超出限制的 GC 开销”错误。我的 CPU 也几乎 100% 运行。

Here 问题是由存储数百万个 String 对象的 HashMap 引起的 - 但我应该“只”存储大约 20.000 个 Node 对象。

请帮我找出我的代码有问题的部分。错误报告下面源代码中标记的行。

这是我的代码:

HashMap<String,TweetNode> allNodes = new HashMap<String,TweetNode>();
    // read file
    try {
        BufferedReader br = new BufferedReader(new FileReader(graphFile));
        noOfNodes = 0;
        String line = br.readLine();
        String firstNode;
        String[] lineContent;
        while (line != null) {
            lineContent = line.split("\t"); // error occurs here!
            // always look at the first node
            firstNode = lineContent[0];
            if (! allNodes.containsKey(firstNode)) {
                allNodes.put(firstNode, new TweetNode(noOfNodes, firstNode));
                noOfNodes++;
            }
            allNodes.get(firstNode).addNeighbour(lineContent[1], Double.valueOf(lineContent[2]));
            line = br.readLine();
        }
        br.close();
    } 
    // ... catch stuff ...
return allNodes;
}

【问题讨论】:

  • 我认为如果你只是调试你的代码应该没问题。
  • @StefanFalk 你能详细说明你的意思吗?你的意思是使用调试工具?我在这方面没有那么有经验。它们会在 GC 收集开始时显示吗?您建议如何使用它?
  • 感谢所有没有 cmets 的反对票。我真的从中学到了很多。 [/讽刺关闭]
  • @anjuta 当您填充HashMap 时,您可能只是在填满现有的堆内存。例如,使用jstat 工具调查使用的堆内存。我不确定,但我的猜测是,由于缺乏对应用程序内存行为的研究,这个问题被否决了。
  • 你能说说你的堆内存大小吗?

标签: java garbage-collection


【解决方案1】:

我在这里看到的唯一问题是您的地图。 Map 正在填满堆内存。您应该在低堆内存的情况下运行您的应用程序。通过访问以下参数检查当前值并将其设置为合理的高值。

标志 Xmx 指定 Java 虚拟机 (JVM) 的最大内存分配池,而 Xms 指定初始内存分配池。

【讨论】:

  • 我还认为 map 可能会导致 Java HeapSize 错误 - 但为什么它会抱怨垃圾收集?我根本不指望我的程序会引起很多 gc 活动——我不会一直创建新对象,它们的内容是相当更新的。我在这里做错了什么?
  • 你的堆内存大小是多少
  • 我没有指定它,但从这里的答案stackoverflow.com/questions/4667483/… 我猜它应该是最大 2gb。
  • 上述链接问题答案中命令给出的完全不可读的信息是:uintx ErgoHeapSizeLimit = 0 {product} uintx HeapSizePerGCThread = 87241520 {product} uintx InitialHeapSize := 130023424 {product} uintx LargePageHeapSizeThreshold = 134217728 {product} uintx MaxHeapSize := 2071986176 {product}
  • 我可以看到大约 2GB 被分配给了 heap..但是尝试为您的应用程序连接到 jconsole 以查看您的应用程序实际获得了多少内存..这为接下来要完成的步骤提供了思路
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 2017-02-24
  • 2017-12-27
  • 2013-07-13
相关资源
最近更新 更多