javac: ending positions generation and DiagnosticListener
Jonathan Gibbons
jonathan.gibbons at oracle.com
Fri Dec 6 09:30:40 PST 2013
On 12/06/2013 09:08 AM, Eugene Zhuravlev wrote:
> Hi,
>
> 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
> com.sun.tools.javac.main.JavaCompiler class.
> 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,
>
This is done deliberately, since there is no way to tell if a client of
the Compiler API needs the information or not.
-- Jon
More information about the compiler-dev
mailing list