在使用ANTLR开发Parser for C ++时,我们进行了批量解析测试用例,其中构造了一个新的解析器来解析每个C ++源文件。开始时性能可以接受 - 每个文件大约15秒。但在解析了大约150多个文件后,每个文件的解析时间越来越长,最后jvm会超出" GC限制超过"错误。
使用JProfiler,我们发现解析每个文件后会逐渐累积许多ATNConfig对象。从大约70M开始,它们稳定地堆积到500M以上,直到堆接近满,GC占用100%的CPU时间。 JProfiler识别的最大对象(保留堆中最多对象的对象)包括DFA []和PredictionContextCache。
需要注意的一点是,我们使用了2个线程来同时运行解析任务。虽然线程不共享任何解析器或解析树对象,但我们注意到ANTLR生成的解析器正在使用静态字段,这可能导致多线程设置中的内存问题。无论如何,这只是一个嫌疑人。
有没有人知道" ATNConfig积累的原因是什么?#34;?有解决方案吗?
答案 0 :(得分:1)
ATNConfig
实例在运行时用于动态DFA构造。所需的实例数是语法和输入的函数。有几种解决方案可供选择:
-Xmx12g
作为起点,看看问题是否是应用程序的内存太少。ATNConfig
都属于DFA
个实例,代表特定决策的DFA。如果您知道包含最多ATNConfig
个实例的决策,您可以在语法中简化这些决策。Recognizer.clearDFA()
定期清除缓存的DFA。请注意,过于频繁地清除DFA会损害性能(如果可能,请不要完全清除DFA)。