4957990: Perm heap bloat in JVM

Treat ProfileData in MDO's as a source of weak, not strong, roots. Fixes the bug for stop-world collection -- the case of concurrent collection will be fixed separately.

Reviewed-by: jcoomes, jmasa, kvn, never
This commit is contained in:
Y. Srinivas Ramakrishna 2009-09-02 00:04:29 -07:00
parent 2491751525
commit c6763b5bad
27 changed files with 385 additions and 65 deletions

View file

@ -27,6 +27,7 @@
GrowableArray<oop>* MarkSweep::_marking_stack = NULL;
GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL;
GrowableArray<DataLayout*>* MarkSweep::_revisit_mdo_stack = NULL;
GrowableArray<oop>* MarkSweep::_preserved_oop_stack = NULL;
GrowableArray<markOop>* MarkSweep::_preserved_mark_stack= NULL;
@ -62,12 +63,37 @@ void MarkSweep::revisit_weak_klass_link(Klass* k) {
void MarkSweep::follow_weak_klass_links() {
// All klasses on the revisit stack are marked at this point.
// Update and follow all subklass, sibling and implementor links.
if (PrintRevisitStats) {
gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes());
gclog_or_tty->print_cr("Revisit klass stack length = %d", _revisit_klass_stack->length());
}
for (int i = 0; i < _revisit_klass_stack->length(); i++) {
_revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive);
}
follow_stack();
}
#if ( defined(COMPILER1) || defined(COMPILER2) )
void MarkSweep::revisit_mdo(DataLayout* p) {
_revisit_mdo_stack->push(p);
}
void MarkSweep::follow_mdo_weak_refs() {
// All strongly reachable oops have been marked at this point;
// we can visit and clear any weak references from MDO's which
// we memoized during the strong marking phase.
assert(_marking_stack->is_empty(), "Marking stack should be empty");
if (PrintRevisitStats) {
gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes());
gclog_or_tty->print_cr("Revisit MDO stack length = %d", _revisit_mdo_stack->length());
}
for (int i = 0; i < _revisit_mdo_stack->length(); i++) {
_revisit_mdo_stack->at(i)->follow_weak_refs(&is_alive);
}
follow_stack();
}
#endif // ( COMPILER1 || COMPILER2 )
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }

View file

@ -23,6 +23,7 @@
*/
class ReferenceProcessor;
class DataLayout;
// MarkSweep takes care of global mark-compact garbage collection for a
// GenCollectedHeap using a four-phase pointer forwarding algorithm. All
@ -65,6 +66,8 @@ class MarkSweep : AllStatic {
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
virtual const bool do_nmethods() const { return true; }
virtual const bool should_remember_mdo() const { return true; }
virtual void remember_mdo(DataLayout* p) { MarkSweep::revisit_mdo(p); }
};
class FollowStackClosure: public VoidClosure {
@ -103,6 +106,7 @@ class MarkSweep : AllStatic {
friend class KeepAliveClosure;
friend class VM_MarkSweep;
friend void marksweep_init();
friend class DataLayout;
//
// Vars
@ -112,6 +116,8 @@ class MarkSweep : AllStatic {
static GrowableArray<oop>* _marking_stack;
// Stack for live klasses to revisit at end of marking phase
static GrowableArray<Klass*>* _revisit_klass_stack;
// Set (stack) of MDO's to revisit at end of marking phase
static GrowableArray<DataLayout*>* _revisit_mdo_stack;
// Space for storing/restoring mark word
static GrowableArray<markOop>* _preserved_mark_stack;
@ -157,6 +163,10 @@ class MarkSweep : AllStatic {
// Class unloading. Update subklass/sibling/implementor links at end of marking phase.
static void follow_weak_klass_links();
// Class unloading. Clear weak refs in MDO's (ProfileData)
// at the end of the marking phase.
static void follow_mdo_weak_refs();
// Debugging
static void trace(const char* msg) PRODUCT_RETURN;
@ -213,7 +223,10 @@ class MarkSweep : AllStatic {
#endif
// Call backs for class unloading
static void revisit_weak_klass_link(Klass* k); // Update subklass/sibling/implementor links at end of marking.
// Update subklass/sibling/implementor links at end of marking.
static void revisit_weak_klass_link(Klass* k);
// For weak refs clearing in MDO's
static void revisit_mdo(DataLayout* p);
};
class PreservedMark VALUE_OBJ_CLASS_SPEC {