JDK-7141956 : Java 7 compiler performance degradation
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u2
  • Priority: P3
  • Status: Resolved
  • Resolution: Cannot Reproduce
  • OS: linux
  • CPU: x86
  • Submitted: 2012-02-01
  • Updated: 2013-04-30
  • Resolved: 2013-04-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7-poolResolved 8Resolved
Related Reports
Relates :  
Description
J2SE Version (please include all output from java -version flag):
7u2


Does this problem occur on J2SE 1.5 or 6ux?  Yes / No (pick one)
No


Operating System Configuration Information (be specific):
64-bit Linux


Bug Description:

Have a large body of inter-dependent code that is built all at once via 
Ant's <javac> task and via the JDK itself in the end.  Moreover use their 
own annotation processor to generate numerous classes that are part of 
this compilation.

Java 6 took 3 minutes and 39 seconds for this.

Java 7 took 36 minutes 50 seconds.

This performance degradation issue would stop customer to move to building 
with Java 7. 

Steps to Reproduce (be specific):

it is really difficult to provide a simple test case to reproduce issues as 
the source and dependencies are sizable and the annotation processor is complex 
unless they ship all of those above along.

Here is the list of their observations on 7u2 on 64-bit Linux:

    * With minor changes, the code body in question compiles with source level 
      1.7 and Java 7. This is good news.

    * Furthering the "good news", Java 7 drops the annoying non-error "symbol 
      not found" errors Java 6 produces for each ungenerated generated file

    * Java 7 also gets through the annotation processing rounds much quicker 
      than Java 6. (It's my opinion the compiler is pretty much eliding all 
      compilation save the running of my processors and the acknowledgement 
      that my processors are producing files, which not only gives the appearance 
      of being faster, but also of making it possible to not report errors)

    * For the same compiler settings (-Xmx2048m -XX:MaxPermSize=370m 
      -XX:+UseCompressedOops), 
      Java 7 takes nearly 37 minutes to go from ant "clean" to "all".  
      This is a task Java 6 completes in 3 1/2 minutes (or less).  J
      ava 7 is 10x slower to compile than Java 6!!!  This, clearly, is bad news.

    * Additionally, Java 7 repeats warnings.  It is not surprising that the 
      same warnings propagate between rounds, what is surprising is that 
      the final round repeats warnings and that the total warning count is 
      the accumulation of every printing.  Specifically, javac reports 16 
      warnings when it should only print 8.  The final round consists of 10 
      printed warnings of which 2 warnings are actually duplicated.  The 
      remaining six consist of the same two warnings printed during each round.  
      It's annoying, but innocuous, that the compiler would report warnings incorrectly.

    * We can get sub-3:00 compile times bumping -Xmx from 2048m to 4096m with Java 7.  
      The compiler's clearly spinning in garbage collection...  It's unclear 
      that all our developers can commit that much RAM to the compiler, though.

    * It turns out 2.5GB of heap gives a time of ~5 minutes and 3GB gives a time of ~3.
      suspect we should be able to swing at least 2.5GB at the problem.


Given this it seems fairly clear that the big issue is the Java 7 compiler requires 
much more memory to perform well for this use case.  The engineer examining this 
issue further speculates based on the observations above that Java 7 delays all 
compilation until after all annotation processing rounds have completed -- thereby 
allowing annotation processors to resolves as many errors as possible prior to 
compilation, but requiring much more memory for the final compilation pass.

Eclipse's "Indigo" SR1 (3.7.1) supports Java 7 and can be invoked from Ant's 
<javac> as well, so that's another possibility.

Comments
comment from the submitter: Overall it seems that javac requires more RAM at certain points in its compilation cycle than it used to. That said, the behavior is also improved in some other respects and overall I'd say it is fine to close this -- as overall Java 7's javac is perfectly acceptable. It did help push us firmly from 32 to 64-bit development, but that's alright.
30-04-2013

I'd be surprised this bug is still reproducible as is, meaning that jdk 7 still as such a significant slowdown, but please investigate.
26-04-2013

EVALUATION There is no inherent change in the compilation model with respect to anno processing rounds. It is and always has been the case that the full compilation is delayed until all processing rounds have completed. One thing that has changed is that javac has gotten better at suppressing unnecessary error messages while performing annotation processing, and that may give rise to the illusion that the compilation is being deferred. The issue with memory usage needs further investigation. I accept it is hard to submit a reasonable test case. However, is it possible to indicate, generally, how many source files are involved, how big are they (LOC), how many files are generated over how many processing rounds, how big are the generated files, and how complex are they (lots of methods? overloaded methods? inner classes? etc). How many additional classes are involved, in how many jar files on the class path? Maybe with some guideline numbers we can emulate the customer's environment without needing the actual code.
02-02-2012