2015-10-02 19 views
5

Tôi đang cố gắng sử dụng ANTLR V4 với trao công khai Java 8 ngữ pháp - https://github.com/antlr/grammars-v4/blob/master/java8/Java8.g4ANTLR V4 + Java8 Grammar -> OutOfMemoryException

tôi tạo ra các tập tin lớp học và cố gắng phân tích Java 8 JRE, nhưng bằng cách nào đó tại java.text.SimpleDateFormat.java nó bị treo với :

java.lang.OutOfMemoryError: GC overhead limit exceeded 

Nó cũng treo, khi tôi đang cố gắng để phân tích rằng tập tin duy nhất một mình.

Điều này có thể được giải quyết bằng cách nào đó không? Rõ ràng ANTLR V4 không thể xử lý các tệp có nhiều hơn 2000 LOC? Đó có phải là một giả định đúng không?

Những gì tôi đã làm như vậy cho đến nay:

  • Thay đổi bộ nhớ giao cho JVM trong nhiều bước từ 256MB đến 4GB - nó sau đó thay đổi để

    java.lang.OutOfMemoryError: Java heap space

  • Để đảm bảo rằng không có vấn đề cú pháp với tệp đầu vào
    Lúc đầu, tôi lấy nửa đầu của tập tin ->phân tích cú pháp có vẻ okay,
    sau đó phá hoại hành động đó và loại bỏ nửa cuối của tập tin ->phân tích cú pháp có vẻ okay

+3

... và bạn tăng dung lượng bộ nhớ java, ví dụ: sử dụng '-Xmx'? – Petesh

+0

Xin chào, Petesh! Tôi đã làm điều đó trước đây - Tôi đã cập nhật câu hỏi của mình ... Thx! –

+0

Nhận xét các phần liên tiếp để tìm mã có vấn đề. –

Trả lời

8

Dường như ngữ pháp trong kho lưu trữ đó dựa trên một tài liệu mà tôi đã viết. Ngữ pháp dựa trên một số chức năng chỉ có sẵn trong số "optimized" fork of ANTLR 4 của tôi để hoạt động tốt. Ngoài việc sử dụng bản phát hành đó, bạn cần thực hiện hai điều sau để tối đa hóa hiệu suất:

  1. Sử dụng chiến lược phân tích hai giai đoạn. Giả sử quy tắc bắt đầu của bạn được gọi là compilationUnit, nó có thể trông giống như sau:

    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. Enable bối cảnh toàn cầu DFA (Tôi bổ sung cái này trong khối mã trước nên bạn không thể bỏ lỡ nó)

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

Xin chào, Sam! Cảm ơn bạn đã trả lời của bạn - nó hoàn toàn chạm vào móng tay :) –

+0

Hi @SamHarwell, tôi cũng có một tệp gây ra gói cứu trợ bộ nhớ GC ở trên. Có khả năng là chức năng cho bản sửa lỗi này sẽ biến nó thành bản phân phối chính của antlr không? Hoặc sẽ/bạn phân phối một .jar cho ngã ba của bạn? (Vì tôi không phải là người gốc thế giới java. Tôi không có bộ công cụ để xây dựng ngã ba của bạn.) – t0rst

+0

@ user138304 là chiếc nĩa "tối ưu" này được tích hợp vào ANTLR 4.6? – t0rst