2015-10-02 7 views
5

Ich versuche ANTLR V4 mit der öffentlich gegeben Java 8 Grammatik zu verwenden - https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4ANTLR V4 + Java8 Grammatik -> OutOfMemoryException

ich die Klassendateien erzeugt und versuchte, die Java 8 JRE, zu analysieren, aber irgendwie bei java.text.SimpleDateFormat.java stürzt mit :

java.lang.OutOfMemoryError: GC overhead limit exceeded 

Es ist auch Abstürze, wenn ich versuche, dass einzelne Datei allein zu analysieren.

Kann das irgendwie gelöst werden? Offensichtlich ANTLR V4 kann nicht mit Dateien mit mehr als 2000 LOC umgehen? Ist das eine korrekte Annahme?

Was ich bisher getan habe:

  • Ändern zugewiesen Speicher JVM in mehreren Schritten von 256 MB bis zu 4 GB - es ändert sich dann zu

    java.lang.OutOfMemoryError: Java Heap-Space

  • Um sicherzustellen, dass es kein syntaktisches Problem mit der Eingabedatei gibt
    Zuerst ich die erste Hälfte der Datei entfernt ->Parsing in Ordnung scheint,
    knöpfte dann diese Aktion und die zweite Hälfte der Datei entfernt ->Parsing in Ordnung scheint

+3

... und Sie haben die Java-Speichergröße zB erhöht mit '-Xmx'? – Petesh

+0

Hallo, Petesh! Ich habe das schon mal gemacht - ich habe meine Frage aktualisiert ... Thx! –

+0

Der Kommentar wird nacheinander ausgegeben, um den problematischen Code zu finden. –

Antwort

8

Es ist wie das aussieht Die Grammatik in diesem Repository basiert auf einer, die ich geschrieben habe. Die Grammatik beruht auf bestimmten Funktionen, die nur in meinem "optimized" fork of ANTLR 4 verfügbar sind, um gut zu funktionieren. Zusätzlich zu, dass die Freisetzung verwenden, müssen Sie die folgenden zwei Dinge zu tun, die Leistung zu maximieren:

  1. Mit der zweistufigen Parsing-Strategie. Angenommen, Ihre Startregel compilationUnit genannt wird, könnte es wie folgt aussehen:

    CompilationUnitContext compilationUnit; 
    try { 
        // Stage 1: High-speed parsing for correct documents 
    
        parser.setErrorHandler(new BailErrorStrategy()); 
        parser.getInterpreter().setPredictionMode(PredictionMode.SLL); 
        parser.getInterpreter().tail_call_preserves_sll = false; 
        compilationUnit = parser.compilationUnit(); 
    } catch (ParseCancellationException e) { 
        // Stage 2: High-accuracy fallback parsing for complex and/or erroneous documents 
    
        // TODO: reset your input stream 
        parser.setErrorHandler(new DefaultErrorStrategy()); 
        parser.getInterpreter().setPredictionMode(PredictionMode.LL); 
        parser.getInterpreter().tail_call_preserves_sll = false; 
        parser.getInterpreter().enable_global_context_dfa = true; 
        compilationUnit = parser.compilationUnit(); 
    } 
    
  2. Aktivieren der globale Kontext DFA (I enthalten diese im Block vorherigen Code, so dass Sie es nicht verfehlen)

    parser.getInterpreter().enable_global_context_dfa = true; 
    
+0

Hallo, Sam! Danke für deine Antwort - es trifft total auf den Nagel :) –

+0

Hi @SamHarwell, ich habe auch eine Datei, die den GC-Speicher Bailout oben verursacht. Gibt es eine Chance, dass die Funktionalität für dieses Update es in die Haupt-Anti-Distribution machen wird? Oder verteilst du ein .jar für deine Gabel? (Da ich kein Eingeborener der Java-Welt bin. Ich habe nicht die Toolsets, um Ihre Gabel zu bauen.) – t0rst

+0

@ user138304 ist diese "optimierte" Gabel in ANTLR 4.6 integriert? – t0rst