public abstract class AtnManager extends Object
Manage ATN to avoid memory leak.
The mutable prediction caches (DFA states, prediction contexts, LL(1) table) live on a private ATN owned by a softly referenced AtnWrapper, not on the generated parser's static ATN. That single decision provides the memory-pressure response: while parsers are active the wrapper is strongly reachable through their interpreters, and once this copy of the runtime goes idle the whole cache graph is only softly reachable, so the collector reclaims it directly — no cleaner thread (which would pin the defining class loader for the life of the JVM, GROOVY-12142), and no clear-on-next-parse canary (which never fires for an idle copy: a build daemon caches one runtime copy per distinct classpath, and every idle copy's fully warmed cache stayed strongly reachable until the daemon spent more time collecting than parsing).
Two deterministic mechanisms bound the cache while a copy is active, and they compose:
groovy.antlr4.cache.size DFA states retained
across the shared ATN; exceeding it replaces the wrapper with a fresh one. The
default scales with the heap so a large daemon keeps a warm working set while a
small JVM stays protected.groovy.antlr4.cache.threshold parses, for workloads that want a fixed
cadence. Off by default.| Modifiers | Name | Description |
|---|---|---|
protected class |
AtnManager.AtnWrapper |
| Modifiers | Name | Description |
|---|---|---|
static ReentrantReadWriteLock.ReadLock |
READ_LOCK |
| Type Params | Return Type | Name and description |
|---|---|---|
|
protected abstract AtnManager.AtnWrapper |
createAtnWrapper() |
|
public ATN |
getATN() |
|
protected AtnManager.AtnWrapper |
getAtnWrapper() |
|
protected abstract boolean |
shouldClearDfaCache() |