为什么会出现GC开销限制?

时间:2017-10-17 03:55:27

标签: java intellij-idea out-of-memory

我正在阅读和解析纯文本文件,逐行阅读,将每一行分成句子,将每个句子分成单词并将它们存储到每个句子和每个文档的列表中。

输入文件包含500万行,因此我将ArrayList的大小设置为5005000.我在IntelliJ中的堆大小如下:

# custom IntelliJ IDEA VM options

-Xms128m
-Xmx8192m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow

我的笔记本电脑有15G内存。在读取450000行之后(如print语句所示),它变得非常慢。几分钟后,我收到了:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

每一行(解析为一个文档)都很短,所以我的15G内存应该足以容纳它。文本文件大小仅为800MB。当我在Windows 10中观看我的性能监视器时,它显示只使用了大约55%的内存,这表示当它死亡时仍有大量可用内存。

一个注意事项,在下面的代码中,我使用" sentence.toCharArray()',因为它不是英语,所以我基本上将每个字符视为我实现中的一个单词。 / p>

只有500万行,为什么它已经死了?

        List<List<List<String>>> allWords = new ArrayList<>(5005000);
        System.out.println("Load text from file: ");
        try {
            BufferedReader br = Utils.fileReader(filePath);

            String line;
            int lineNo = 0;
            while ((line = br.readLine()) != null) {
                List<List<String>> wordsPerDoc = new ArrayList<>();
                for (String sentence : segment(line)) {
                    List<String> wordsPerSentence = new ArrayList<>();
                    for (Character c : sentence.toCharArray()) {
                        wordsPerClause.add(Character.toString(c));
                    }
                    wordsPerDoc.add(wordsPerSentence);
                }
                allWords.add(wordsPerDoc);
                lineNo++;
                if(lineNo % 500000 ==0) {
                    System.out.println(lineNo);
                }
            }
            System.out.println("Loaded text from file. ");

            br.close();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

public List<String> segment(final String line) {
        List<String> sentences = new ArrayList<>();
        StringTokenizer tokenizer = new StringTokenizer(line, OtherConstants.BASIC_TOKENIZATION_DELIMITER, true);
        while (tokenizer.hasMoreTokens()) {
            String word = tokenizer.nextToken();
                sentences.add(word);
        }
        return sentences;
    }

1 个答案:

答案 0 :(得分:1)

您正在更改 IntelliJ的内存配置文件

要为您的应用更改它:转到右上角的运行菜单;找到你的主要班级;点击“编辑配置”;并将“VM选项”设置为-Xmx4g,以获得适用于您应用的4 GB堆。

https://www.jetbrains.com/help/idea/run-debug-configuration-application.html了解文档