RFR(S): 8173743: Failures during class definition can lead to memory leaks in metaspace

David Holmes david.holmes at oracle.com
Tue Feb 7 05:06:29 UTC 2017

Hi Volker,

On 7/02/2017 4:40 AM, Volker Simonis wrote:
> Hi,
> can somebody please review the following change:
> http://cr.openjdk.java.net/~simonis/webrevs/2017/8173743.v1/
> https://bugs.openjdk.java.net/browse/JDK-8173743

Functional change looks good - took me a while to work through the 
permutations. :)

Have a few comments on the test, mostly nits.

I believe an Oracle copyright line is also required.

linkageErrors is not incremented in a thread-safe way, and should also 
be volatile. I think you are just using this as a rough count, but if so 
document that and at least declare it volatile so it is reported with a 
current value if needed.

256             // executing and one another version

Either: "one other version" or "another version" (occurs elsewhere)

  283                 catch (java.lang.SecurityException jlse) {
  284                     // Expected
  285                 }

If the SecurityException is always expected then should not absence of 
it be reported as an error?

288             // We expect to have two instances of DefineClass here: 
the initial version in which we are
291             System.out.println("Should have 1 DefineClass instances 
and we have: " + count);

Comment and code do not match: do we expect one instance or two?

  292             System.gc();
  293             System.out.println("System.gc()");
  294             count = getClassStats("DefineClass");
  295             // At least after System.gc() the failed loading 
attempts should leave no instances around!

Are we guaranteed, for all GC's, that a single call to System.gc(), will 
clear the unwanted instances? (This applies to all test cases.)

  353             // kept alive by this main methidf

Typo: methidf

367                 catch (UnsupportedOperationException uoe) {
368                     // Expected
369                 }

Ditto re not getting the exception - should this report an error?


> It fixes some problems during class definitions where instance klasses
> can leak into the metaspace in cases where the class definition fails
> after the class was successfully loaded from the bytecode stream.
> There are actually two cases to consider:
> 1. If we load the same class several times into the same class loader,
> we will get LinkageErrors after the first successful load. But
> nevertheless we will first construct a new instanceKlass for each new
> load attempt and this instanceKlass will never be deleted.
> 2. If we have a parallel capable class loader, set
> -XX:-UnsyncloadClass and/or -XX:+AllowParallelDefineClass and load a
> class from several threads at the same time in parallel, it can happen
> that we create several instance klasses for the same class. At the end
> only one of them will be added to the system dictionary, but all the
> other ones will never be deleted. Notice that if we run this scenario
> without setting either of -XX:-UnsyncloadClass or
> -XX:+AllowParallelDefineClass, this scenario will degrade into the
> case above and we will get LinkageErrors for all but the first
> successful load.
> The change comes with a regression test which checks for the two cases
> just describe and also for the failing class redefinition case, which
> currently doesn't produce a memory leak.
> I've already committed this to the hs-demo-submit/hotspot/ forest and
> it went through without a problem. So in theory it should have passed
> the internal JPRT tests although I'm not sure if the test set of the
> "demo-submit" forest and the real hotspot repo are exactly the same
> (CC'ed Tim and Brian).
> Thank you and best regards,
> Volker

More information about the hotspot-runtime-dev mailing list