我目前正在尝试使用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/