【问题标题】:Java GC overhead limit exceeded超出 Java GC 开销限制
【发布时间】:2015-07-01 21:28:32
【问题描述】:

我正在尝试预处理一个大的 txt 文件 (10G),并将其存储在二进制文件中以备将来使用。随着代码的运行,它会变慢并以

结尾

线程“主”java.lang.OutOfMemoryError 中的异常:GC 开销 超出限制

输入文件的结构如下

200020000000008;0;2
200020000000004;0;2
200020000000002;0;2
200020000000007;1;2

这是我正在使用的代码:

        String strLine;

        FileInputStream fstream = new FileInputStream(args[0]);
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); 

        //Read File Line By Line
        HMbicnt map = new HMbicnt("-1");
        ObjectOutputStream  outputStream = null;
        outputStream = new ObjectOutputStream(new FileOutputStream(args[1]));

        int sepIndex = 15;

        int sepIndex2 = 0;
        String str_i = "";
        String bb = "";
        String bbBlock = "init";

        int cnt = 0;
        lineCnt = 0;
        while ((strLine = br.readLine()) != null)   {
            //rozparsovat radek         
            str_i = strLine.substring(0, sepIndex);
            sepIndex2 = strLine.substring(sepIndex+1).indexOf(';');
            bb = strLine.substring(sepIndex+1, sepIndex+1+sepIndex2);
            cnt = Integer.parseInt(strLine.substring(sepIndex+1+sepIndex2+1));
            if(!bb.equals(bbBlock)){
                outputStream.writeObject(map);
                outputStream.flush();
                map = new HMbicnt(bb);
                map.addNew(str_i + ";" + bb, cnt);
                bbBlock = bb;
            }
            else{
                map.addNew(str_i + ";" + bb, cnt);
            }
        }
        outputStream.writeObject(map);

        //Close the input stream
        br.close();
        outputStream.writeObject(map = null);
        outputStream.close();

基本上,它通过 in 文件并将数据存储到对象 HMbicnt(这是一个哈希映射)。一旦在第二列中遇到新值,它应该将对象写入输出文件,释放内存并继续。

感谢您的帮助。

【问题讨论】:

  • 要么 bblocks 从不重复,导致你不断添加到同一个地图,要么HMbicnt 的实现在做一些可疑的事情。你能展示addNew()的实现以及它调用的任何方法吗?

标签: java garbage-collection hashmap


【解决方案1】:

我认为问题不在于 10G 在内存中,而在于您创建了太多的 HashMap。也许您可以清除 HashMap 而不是在不再需要它后重新创建它。 java.lang.OutOfMemoryError: GC overhead limit exceeded好像也出现过类似的问题,也是关于HashMaps

【讨论】:

  • 你可能是对的。当然,需要注意的重要一点是,这两个问题都可以通过简单地减少程序所需的内存总量来避免。
【解决方案2】:

简单地说,您使用了太多内存。因为,正如您所说,您的文件是 10 GB,所以您无法将其全部放入内存中(当然,除非您碰巧有超过 10 GB 的 RAM 并且已将 Java 配置为使用它)。

从我的代码和描述中可以看出,您正在将 整个 文件读入内存,并在这样做时将其添加到一个巨大的内存映射中,然后将结果写入输出。这是不可行的。您需要重新设计代码以就地工作(即在任何给定时间仅将文件的一小部分保留在内存中)。

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 2017-12-27
    • 2013-07-13
    • 2018-03-29
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多