javac: ending positions generation and DiagnosticListener
jeka at intellij.com
Fri Dec 6 09:08:56 PST 2013
My question is about the strange behavior javac exhibits when invoked
via Compiler API. In the latest versions of IntelliJ IDEA we are using
Compiler API for javac invocation. After switching to this approach
we've received a number of complaints from our users about javac's high
memory usage. Large projects requiring compilation of big number of
large files in one go are especially affected. Surprisingly compilation
of the same project using the same JDK, but with ant script requires
less heap memory for javac.
After digging into javac's sources I found the reason: extra memory is
needed for the "end positions" data gathered by the compiler.
Whether this option is on is controlled by the flag "genEndPos" in
The flag is initialized in constructor like this:
genEndPos = options.isSet(XJCOV) ||
context.get(DiagnosticListener.class) != null;
So a mere presence of a DiagnosticListener makes compiler store end
positions and probably related stuff. As we use Compiler API, we add
this listener and thus this data is always generated, even if not used.
The question is: is this done deliberately, or this is just a "legacy
code" that can be corrected? Javac's excessive memory usage can
dramatically affect performance when compiling large projects, so
removing the check "context.get(DiagnosticListener.class) != null" would
be a good optimization.
Currently we can only advice our users to increase maximum heap size for
the build process, as there is no way to switch this flag off.
Thanks in advance for any information,
"Develop with pleasure!"
More information about the compiler-dev