Java 读取大型管道分隔值文件时超出了GC开销限制

Java 读取大型管道分隔值文件时超出了GC开销限制,java,parsing,delimiter,large-files,Java,Parsing,Delimiter,Large Files,我正试图解析一个大文件(650万行),但遇到了提到的内存不足错误。我使用同样的方法来读取大约50K行的其他文件,它工作得相当快。在这里,它运行非常慢,然后由于错误而失败。我最初有2GB专用于intelliJ,我将其更改为4GB(-Xmx4000m),然后是6GB(-Xmx6000m),最后仍然出现相同的错误。我的电脑只有8GB内存,所以我不能再高了。有什么建议吗 谢谢 public static List<UmlsEntry> umlsEntries(Resource resourc

我正试图解析一个大文件(650万行),但遇到了提到的内存不足错误。我使用同样的方法来读取大约50K行的其他文件,它工作得相当快。在这里,它运行非常慢,然后由于错误而失败。我最初有2GB专用于intelliJ,我将其更改为4GB(-Xmx4000m),然后是6GB(-Xmx6000m),最后仍然出现相同的错误。我的电脑只有8GB内存,所以我不能再高了。有什么建议吗

谢谢

public static List<UmlsEntry> umlsEntries(Resource resource) throws 
 IOException {
 return CharStreams.readLines(new InputStreamReader(resource.getInputStream())).stream().distinct()
    .map(UmlsParser::toUmlsEntry).collect(Collectors.toList());
}

private static UmlsEntry toUmlsEntry(String line) {
 String[] umlsEntry = line.split("|");

 return new UmlsEntry(umlsEntry[UNIQUE_IDENTIFIER_FOR_CONCEPT_COLUMN_INDEX],
    umlsEntry[LANGUAGE_OF_TERM_COLUMN_INDEX], umlsEntry[TERM_STATUS_COLUMN_INDEX],
    umlsEntry[UNIQUE_IDENTIFIER_FOR_TERM_COLUMN_INDEX], umlsEntry[STRING_TYPE_COLUMN_INDEX],
    umlsEntry[UNIQUE_IDENTIFIER_FOR_STRING_COLUMN_INDEX],
    umlsEntry[IS_PREFERRED_STRING_WITHIN_THIS_CONCEPT_COLUMN_INDEX],
    umlsEntry[UNIQUE_IDENTIFIER_FOR_ATOM_COLUMN_INDEX], umlsEntry[SOURCE_ASSERTED_ATOM_INDENTIFIER_COLUMN_INDEX],
    umlsEntry[SOURCE_ASSERTED_CONCEPT_IDENTIFIER_COLUMN_INDEX],
    umlsEntry[SOURCE_ASSERTED_DESCRIPTOR_IDENTIFIER_COLUMN_INDEX],
    umlsEntry[ABBREVIATED_SOURCE_NAME_COLUMN_IDENTIFIER_COLUMN_INDEX],
    umlsEntry[ABBREVIATION_FOR_TERM_TYPE_IN_SOURCE_VOCABULARY_COLUMN_INDEX],
    umlsEntry[MOST_USEFUL_SOURCE_ASSERTED_IDENTIFIER_COLUMN_INDEX], umlsEntry[STRING_COLUMN_INDEX],
    umlsEntry[SOURCE_RESTRICTION_LEVEL_COLUMN_INDEX], umlsEntry[SUPPRESSIBLE_FLAG_COLUMN_INDEX],
    umlsEntry[CONTENT_VIEW_FLAG_COLUMN_INDEX]);
 }
公共静态列表umlsEntries(资源)抛出
IOException{
返回CharStreams.readLines(新的InputStreamReader(resource.getInputStream())).stream().distinct()
.map(UmlsParser::toumlssentry).collect(Collectors.toList());
}
专用静态UmlsEntry toUmlsEntry(字符串线){
字符串[]umlsEntry=line.split(“|”);
返回新的UmlsEntry(UmlsEntry[概念列索引的唯一标识符],
umlsEntry[术语列索引的语言]、umlsEntry[术语状态列索引],
umlsEntry[术语列索引的唯一标识符]、umlsEntry[字符串类型列索引],
umlsEntry[字符串列索引的唯一标识符],
umlsEntry[在本概念列索引中是首选字符串],
umlsEntry[原子列索引的唯一标识符]、umlsEntry[源原子列索引的唯一标识符],
umlsEntry[源\u断言\u概念\u标识符\u列\u索引],
umlsEntry[源\断言\描述符\标识符\列\索引],
umlsEntry[缩写的源名称列标识符列索引],
umlsEntry[来源词汇栏索引中术语类型的缩写],
umlsEntry[最有用的\u源\u断言的\u标识符\u列\u索引]、umlsEntry[字符串\u列\u索引],
umlsEntry[源限制\u级别\u列索引]、umlsEntry[可抑制的\u标志\u列索引],
umlsEntry[内容\视图\标志\列\索引];
}

您需要一次处理几行,以避免耗尽所有可用内存,因为文件不适合内存
CharStreams.readLines
令人困惑地不是流式处理。它一次读取所有行并返回一个列表。这行不通。请改为尝试
File.lines
。我怀疑您也会在
distinct
上遇到麻烦。它需要跟踪所有行的所有哈希值,如果这个值膨胀得太大,那么您可能也必须改变这种策略。哦,如果你没有足够的内存来保存结果,
collect
也不会起作用。然后,您可能希望写入新文件或数据库等

下面是一个示例,说明如何从文件中流式传输行,计算不同的条目并打印每行的md5:

Files.lines(FileSystems.getDefault().getPath("/my/file"))
            .distinct()
            .map(DigestUtils::md5)
            .forEach(System.out::println);

如果在检测不同的行时遇到问题,请先对文件进行适当排序,然后仅过滤出相同的相邻行。

请发布堆栈跟踪。哪一行导致了错误?啊,我没有复制它,我出去吃午饭时会运行它,它占用了我所有的内存,所以我几乎不能做任何其他事情。很快就会联系上……是的,我的机器没有足够的功能,无法像我所有的程序一样,在不退出的情况下保存整个列表。可以很好地加载所有行,但是添加到列表中,一旦超过100万,就会变得非常缓慢。