简体   繁体   English

如何延迟正确初始化 Java 中的 static 数组字段

[英]How to lazy correctly initialize a static array field in Java

The generated Antlr4 lexers and parsers have some internal data they put on the heap which isn't necessary after parsing that I want to free up to clear heap space and prevent memory overflows.生成的 Antlr4 词法分析器和解析器有一些内部数据放在堆上,这些数据在解析后不需要释放以清除堆空间并防止 memory 溢出。 I am using lazy initializers to do so and then delete them afterward.我正在使用惰性初始化器来执行此操作,然后将它们删除。 Most of them were easy to do.他们中的大多数都很容易做到。

However there is an array that is complaining when I do so.但是,当我这样做时,有一个数组在抱怨。 I need to know the correct idiom for doing it.我需要知道正确的习惯用法。 I only have one thread (and I only use the lexer/parser once (*except for in testing, see below)) so I'm not really concerned about synchronization, but I would like to have warning/lint free compiles, and "findBugs" doesn't like the code I am using.我只有一个线程(而且我只使用过一次词法分析器/解析器(*除了在测试中,见下文))所以我并不真正关心同步,但我希望有警告/lint free 编译,并且“ findBugs" 不喜欢我使用的代码。

Here is the initial code I tried:这是我尝试的初始代码:

public class Lexer;
    protected static DFA[] = null; 
...
    public Lexer(CharStream input) {
       if (_decisionToDFA == null) {
          _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
          for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
              _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
          }
        }
    }
...
    public void closeLexer() {
       _decisionToDFA = null;
    }

The code in the middle which attempts to do the static initialization is the code FindBugs complains about.中间尝试进行 static 初始化的代码是 FindBugs 抱怨的代码。 I tried the following but it didn't help.我尝试了以下但没有帮助。

       if (_decisionToDFA == null) {
          // build it here locally
          DFA _local_decisionToDFA[] = new DFA[_ATN.getNumberOfDecisions()];
          for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
              _local_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
          }
        _decisionToDFA = _local_decisionToDFA;  // then just move the reference
        }

*below: *以下:

The exception is when I am running unit tests.例外是当我运行单元测试时。 The unit tests of which there are currently just a little over 2k, each parse some fragment of code and the walk the generated parse tree and compute something and check that the computation matches the proper semantics.目前只有 2k 多一点的单元测试,每个都解析一些代码片段并遍历生成的解析树并计算一些东西并检查计算是否匹配正确的语义。

Unfortunately, the internal data (eg these arrays and some caches, etc.) that the lexer and parser build to do so, slowly accumulates and eventually uses up all the heap space causing the tests near the end to run out of memory, which is why I need to free them.不幸的是,词法分析器和解析器为此构建的内部数据(例如,这些 arrays 和一些缓存等)缓慢累积并最终耗尽所有堆空间,导致接近末尾的测试用完 memory,即为什么我需要释放他们。 In production runs, each compilation is a separate process with its own address space, so it wouldn't be as much an issue.在生产运行中,每次编译都是一个独立的进程,有自己的地址空间,所以这不会是一个太大的问题。

Description Resource    Path    Location    Type
Incorrect lazy initialization and update of static field Lexer._decisionToDFA in new Lexer(CharStream) [Scary(6), High confidence]  PowerShellLexer.java    /src/main/java/Lexer    line 413    FindBugs Problem (Scary)

It turns out if you put the code into a function, that seems to quiet the findBugs error message.事实证明,如果您将代码放入 function 中,这似乎可以消除 findBugs 错误消息。

public class Lexer;
    protected static DFA[] = null; 
...
    private DFA[] createDecisionToDFA() {
          // build it here locally
          DFA _local_decisionToDFA[] = new DFA[_ATN.getNumberOfDecisions()];
          for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
              _local_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
          }
        return _local_decisionToDFA;  // then just move the reference
        }

    public Lexer(CharStream input) {
       if (_decisionToDFA == null) {
          _decisionToDFA = createDecisionToDFA();
        }
    }
...
    public void closeLexer() {
       _decisionToDFA = null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM