6794422: Perm gen expansion policy for concurrent collectors
authorysr
Fri, 01 Oct 2010 16:12:54 -0700
changeset 6765 f8d7d46aa4ff
parent 6764 82eecb6073ad
child 6767 476e988061bb
6794422: Perm gen expansion policy for concurrent collectors Summary: Concurrent collectors should expand the perm gen without a full STW GC, but possibly by triggering a concurrent collection. Temporary band-aid for G1 where no concurrent collection is kicked off since the perm gen is not collected concurrently. Reviewed-by: johnc
hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp
hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp
hotspot/src/share/vm/includeDB_core
hotspot/src/share/vm/memory/permGen.cpp
hotspot/src/share/vm/memory/permGen.hpp
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp	Thu Sep 30 12:15:13 2010 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp	Fri Oct 01 16:12:54 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,18 @@
   }
 }
 
+HeapWord* CMSPermGen::request_expand_and_allocate(Generation* gen,
+                                                  size_t size,
+                                                  GCCause::Cause prev_cause /* ignored */) {
+  HeapWord* obj = gen->expand_and_allocate(size, false);
+  if (gen->capacity() >= _capacity_expansion_limit) {
+    set_capacity_expansion_limit(gen->capacity() + MaxPermHeapExpansion);
+    assert(((ConcurrentMarkSweepGeneration*)gen)->should_concurrent_collect(),
+           "Should kick off a collection if one not in progress");
+  }
+  return obj;
+}
+
 void CMSPermGen::compute_new_size() {
   _gen->compute_new_size();
 }
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp	Thu Sep 30 12:15:13 2010 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp	Fri Oct 01 16:12:54 2010 -0700
@@ -33,6 +33,10 @@
   // The "generation" view.
   ConcurrentMarkSweepGeneration* _gen;
 
+  // Override default implementation from PermGen
+  virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size,
+                                                GCCause::Cause prev_cause);
+
  public:
   CMSPermGen(ReservedSpace rs, size_t initial_byte_size,
              CardTableRS* ct, FreeBlockDictionary::DictionaryChoice);
--- a/hotspot/src/share/vm/includeDB_core	Thu Sep 30 12:15:13 2010 -0700
+++ b/hotspot/src/share/vm/includeDB_core	Fri Oct 01 16:12:54 2010 -0700
@@ -3456,6 +3456,7 @@
 permGen.hpp                             generation.hpp
 permGen.hpp                             handles.hpp
 permGen.hpp                             iterator.hpp
+permGen.hpp                             mutexLocker.hpp
 permGen.hpp                             virtualspace.hpp
 
 placeholders.cpp                        fieldType.hpp
--- a/hotspot/src/share/vm/memory/permGen.cpp	Thu Sep 30 12:15:13 2010 -0700
+++ b/hotspot/src/share/vm/memory/permGen.cpp	Fri Oct 01 16:12:54 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,17 @@
 #include "incls/_precompiled.incl"
 #include "incls/_permGen.cpp.incl"
 
+HeapWord* PermGen::request_expand_and_allocate(Generation* gen, size_t size,
+                                               GCCause::Cause prev_cause) {
+  if (gen->capacity() < _capacity_expansion_limit ||
+      prev_cause != GCCause::_no_gc || UseG1GC) {  // last disjunct is a temporary hack for G1
+    return gen->expand_and_allocate(size, false);
+  }
+  // We have reached the limit of capacity expansion where
+  // we will not expand further until a GC is done; request denied.
+  return NULL;
+}
+
 HeapWord* PermGen::mem_allocate_in_gen(size_t size, Generation* gen) {
   GCCause::Cause next_cause = GCCause::_permanent_generation_full;
   GCCause::Cause prev_cause = GCCause::_no_gc;
@@ -37,10 +48,14 @@
       if ((obj = gen->allocate(size, false)) != NULL) {
         return obj;
       }
-      if (gen->capacity() < _capacity_expansion_limit ||
-          prev_cause != GCCause::_no_gc) {
-        obj = gen->expand_and_allocate(size, false);
-      }
+      // Attempt to expand and allocate the requested space:
+      // specific subtypes may use specific policy to either expand
+      // or not. The default policy (see above) is to expand until
+      // _capacity_expansion_limit, and no further unless a GC is done.
+      // Concurrent collectors may decide to kick off a concurrent
+      // collection under appropriate conditions.
+      obj = request_expand_and_allocate(gen, size, prev_cause);
+
       if (obj != NULL || prev_cause == GCCause::_last_ditch_collection) {
         return obj;
       }
@@ -119,5 +134,5 @@
   if (_gen->capacity() > desired_capacity) {
     _gen->shrink(_gen->capacity() - desired_capacity);
   }
-  _capacity_expansion_limit = _gen->capacity() + MaxPermHeapExpansion;
+  set_capacity_expansion_limit(_gen->capacity() + MaxPermHeapExpansion);
 }
--- a/hotspot/src/share/vm/memory/permGen.hpp	Thu Sep 30 12:15:13 2010 -0700
+++ b/hotspot/src/share/vm/memory/permGen.hpp	Fri Oct 01 16:12:54 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,15 +30,26 @@
 class GenRemSet;
 class CSpaceCounters;
 
-// PermGen models the part of the heap
+// PermGen models the part of the heap used to allocate class meta-data.
 
 class PermGen : public CHeapObj {
   friend class VMStructs;
  protected:
   size_t _capacity_expansion_limit;  // maximum expansion allowed without a
                                      // full gc occurring
+  void set_capacity_expansion_limit(size_t limit) {
+    assert_locked_or_safepoint(Heap_lock);
+    _capacity_expansion_limit = limit;
+  }
 
   HeapWord* mem_allocate_in_gen(size_t size, Generation* gen);
+  // Along with mem_allocate_in_gen() above, implements policy for
+  // "scheduling" allocation/expansion/collection of the perm gen.
+  // The virtual method request_...() below can be overridden by
+  // subtypes that want to implement a different expansion/collection
+  // policy from the default provided.
+  virtual HeapWord* request_expand_and_allocate(Generation* gen, size_t size,
+                                                GCCause::Cause prev_cause);
 
  public:
   enum Name {