JDK-5093520 : objects being kept alive in perm gen and old gen when debugger attached
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 1.4.0,1.4.2_05,5.0,6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_2000
  • CPU: generic,x86
  • Submitted: 2004-08-27
  • Updated: 2005-09-22
  • Resolved: 2005-09-22
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.
Other JDK 6
1.4.2_12Fixed 6 b53Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Name: dd4877			Date: 08/27/2004

###@###.### 2004-08-27

The following bug:

    4979680 2/2 objects being kept alive in perm gen and old gen

was split into two phases. The first phase restored the Merlin (1.4)
behavior and I was supposed to file a bug for the second phase. I believe
I forgot to file the phase 2 bug so I'm doing so now.

Here is an e-mail that I sent on this issue on 2004.01.28:


I've added Jon since he filed the original bug and I've added Coleen
since she loves SystemDictionary issues 

Here are my first pass mullings on this bug...

1) placeholders for primitive arrays are added in
   SystemDictionary::resolve_array_class_or_null() via a
   placeholders()->find_and_add() call. There are two other
   calls to find_and_add(), but those are place holders for
   regular classes and not array classes.

2) placeholders are removed by placeholders()->find_and_remove()
   in the case of errors or placeholders()->remove_entry() for
   non-error cases. The three find_and_remove() calls are in
   cases of errors with regular classes and not array classes.
   The one remove_entry() call is made from SystemDictionary::
   update_dictionary() when it is going to replace the placeholder
   with a real class entry. update_dictionary() is only called
   for real classes and not array classes

3) from my observations in points 1 & 2 above, it certainly looks
   like those placeholders for primitive arrays are not deleted
   by either code path in class PlaceholderTable.

4) I found that the placeholders are properly GC'ed which isn't a
   surprise since we would have some serious stability issues with
   GCAlot during heavy class loading:

5) Dictionary::do_unloading() loops through the dictionary and removes
   entries if the entry's loader is dead. It seems like we need similar
   functionality for the placeholder table.
   Dictionary::do_unloading() has the following comment:

     // The placeholder array has been handled in always_strong_oops_do.

   Before primitive arrays were added to the placeholder array, I
   think the comment was correct. Now, always_strong_oops_do() only
   handles oop relocation and not "unloading".
   SystemDictionary::do_unloading() calls Dictionary::do_unloading()
   and it seems like SystemDictionary::do_unloading() is the right
   place to remove any stale placeholder entries.

I'm thinking that we need to add PlaceholderTable()::do_unloading()
that sort of mirrors what Dictionary::do_unloading() (no event
posting though). This new "unloading" routine should be called from


So am I on the right track here?


###@###.### 10/13/04 04:14 GMT

EVALUATION -- This fix has been back-ported to 5.0 update 7.

EVALUATION -- This bug has been fixed for mustang b53. This bug has 40 votes on the JDC so it would be good if some of those that voted could download b53 or newer from the mustang site (https://mustang.dev.java.net) for try it out. b51 is the latest build and b53 should be available on 23/9. Once we are happy that the fix hasn't introduced any regressions then we can see about getting the fix into a 5.0 update release.

EVALUATION (2005-09-08) It has just come to light that this issue impacts all applications when there is a JVMTI agent. That is, once there is a JVMTI agent it means that placeholders for primitive array classes are added to the system dictionary. As these placeholders aren't removed it means that the class loader cannot be GC'ed which can be serious in J2EE applications. Another point is that with late-binding agents it is possible that GetClassLoaderClasses will return an incomplete list of classes so an alternative solution to using placeholders should be investigated. -- There are two alternative approaches to take on this issue: 1. Re-examine the specifcation of GetClassloaderClasses to see if it really necessary to record a loader as the initiating loader of a primitive array class (is this important to agents?). Only the boot class loader will be the defining loader of these classes. 2. If GetClassloaderClasses is required to return primitive array classes then the implementation needs to be updated so that the placeholders are removed, and secondly that the recording of loaders as initiating loaders of primitive array classes is always enabled (not just when there is a jvmti environment). -- We have an outline solution to this issue and hope to have it ready for mustang b53.

EVALUATION Post bug 4450091 fix, the primitive array types are kept in the place-holder list in system dictionary. These references are not cleaned up during 'gc'. These primitive array types are added only in jvmdi::enabled() mode. Thereby causing other objects not to be collected. We may need to move the type-references from place-holder list (which is used for temporary purpose) to the normal system dictionary list (which will be 'gc'ed). This also can be done only in the jvmdi::enabled() mode. ###@###.### 10/19/04 04:29 GMT --

PUBLIC COMMENTS Name: dd4877 Date: 08/27/2004 . ======================================================================