我目前正在尝试使用Java Runtime使用ANTLR解析大文件(约70万行)。该文件太大,并且解析会导致“内存不足”异常(分配了超过8GB的RAM之后)。

由于我不在乎将所有内容解析在一起,因此我能够将文件拆分为几个文件,每个文件包含一些功能。我现在正在运行多个线程,以解析每个获得的文件。

这是每个线程的runnable的run()函数:

public void run() {
    System.out.println("Starting to parse file " + this.filename);
    try {
        org.antlr.v4.runtime.CharStream stream = CharStreams.fromFileName(this.filename, Charset.defaultCharset());
        CPP14Lexer lexer = new CPP14Lexer(stream);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        CPP14Parser parser = new CPP14Parser(tokens);
        ParseTree tree = parser.translationunit();
        lexer = null;
        tokens = null;
        parser = null;
        tree = null;
    } catch (IOException e) {
        e.printStackTrace();
    }
    TheParser.current_temp_file.decrementAndGet();
    System.out.println("Finished parsing file " + this.filename);
}


这是我的问题:线程运行良好。为了避免出现内存问题,我将它们三乘三运行(使用“ TheParser.current_temp_file”静态原子整数)。但是,线程永远不会完全终止。因此,执行后,它们仍然存在,并且内存不断增加。

我认为问题可能来自从未关闭过的CharStream。但是,org.antlrv4.runtime.CharStream类中没有此类方法。

您知道问题出在哪里以及如何解决吗?

谢谢!

最佳答案

确实没有close方法,因为CharStream是通用接口,而CharStreams可以构建CharStream实例,因为您可以从许多来源构建许多不同的实现。对于其中的某些内容(例如CharStreams.fromString()),根本没有要关闭的内容,对于其他一些内容,则应该直接关闭基础流。

source code看来,文件被读入内存中,然后甚至在获得CharStreams实例之前就已在CharStream中关闭。

我建议您调查而不是猜测。它仍然在内存中崩溃吗?使用-XX:+HeapDumpOnOutOfMemoryError运行您的应用程序,并调查产生的内存转储。线程不退出吗?使用探查器(例如VisualVM)查看线程卡住的位置。

关于java - 关闭ANTLR4 CharStream(Java运行时)-OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54185551/

10-12 04:56