8130265: gctests/LargeObjects/large001 fails with OutOfMemoryError: Java heap space
authoraharlap
Wed, 30 Sep 2015 18:09:40 -0400
changeset 33108 6714a3872d8f
parent 33107 77bf0d2069a3
child 33109 3eebb5e50129
child 33113 ca9ef69338be
8130265: gctests/LargeObjects/large001 fails with OutOfMemoryError: Java heap space Summary: Avoided G1 OutOfMemoryError by adding extra expand heap call Reviewed-by: jwilhelm, tschatzl
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Sep 30 09:07:21 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Sep 30 18:09:40 2015 -0400
@@ -1801,21 +1801,20 @@
   }
 }
 
-
-HeapWord*
-G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
-                                           AllocationContext_t context,
-                                           bool* succeeded) {
-  assert_at_safepoint(true /* should_be_vm_thread */);
-
-  *succeeded = true;
+HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size,
+                                                            AllocationContext_t context,
+                                                            bool do_gc,
+                                                            bool clear_all_soft_refs,
+                                                            bool expect_null_mutator_alloc_region,
+                                                            bool* gc_succeeded) {
+  *gc_succeeded = true;
   // Let's attempt the allocation first.
   HeapWord* result =
     attempt_allocation_at_safepoint(word_size,
                                     context,
-                                    false /* expect_null_mutator_alloc_region */);
+                                    expect_null_mutator_alloc_region);
   if (result != NULL) {
-    assert(*succeeded, "sanity");
+    assert(*gc_succeeded, "sanity");
     return result;
   }
 
@@ -1825,41 +1824,58 @@
   // do something smarter than full collection to satisfy a failed alloc.)
   result = expand_and_allocate(word_size, context);
   if (result != NULL) {
-    assert(*succeeded, "sanity");
+    assert(*gc_succeeded, "sanity");
     return result;
   }
 
-  // Expansion didn't work, we'll try to do a Full GC.
-  bool gc_succeeded = do_collection(false, /* explicit_gc */
-                                    false, /* clear_all_soft_refs */
-                                    word_size);
-  if (!gc_succeeded) {
-    *succeeded = false;
-    return NULL;
-  }
-
-  // Retry the allocation
-  result = attempt_allocation_at_safepoint(word_size,
-                                           context,
-                                           true /* expect_null_mutator_alloc_region */);
-  if (result != NULL) {
-    assert(*succeeded, "sanity");
+  if (do_gc) {
+    // Expansion didn't work, we'll try to do a Full GC.
+    *gc_succeeded = do_collection(false, /* explicit_gc */
+                                  clear_all_soft_refs,
+                                  word_size);
+  }
+
+  return NULL;
+}
+
+HeapWord* G1CollectedHeap::satisfy_failed_allocation(size_t word_size,
+                                                     AllocationContext_t context,
+                                                     bool* succeeded) {
+  assert_at_safepoint(true /* should_be_vm_thread */);
+
+  // Attempts to allocate followed by Full GC.
+  HeapWord* result =
+    satisfy_failed_allocation_helper(word_size,
+                                     context,
+                                     true,  /* do_gc */
+                                     false, /* clear_all_soft_refs */
+                                     false, /* expect_null_mutator_alloc_region */
+                                     succeeded);
+
+  if (result != NULL || !*succeeded) {
     return result;
   }
 
-  // Then, try a Full GC that will collect all soft references.
-  gc_succeeded = do_collection(false, /* explicit_gc */
-                               true,  /* clear_all_soft_refs */
-                               word_size);
-  if (!gc_succeeded) {
-    *succeeded = false;
-    return NULL;
-  }
-
-  // Retry the allocation once more
-  result = attempt_allocation_at_safepoint(word_size,
-                                           context,
-                                           true /* expect_null_mutator_alloc_region */);
+  // Attempts to allocate followed by Full GC that will collect all soft references.
+  result = satisfy_failed_allocation_helper(word_size,
+                                            context,
+                                            true, /* do_gc */
+                                            true, /* clear_all_soft_refs */
+                                            true, /* expect_null_mutator_alloc_region */
+                                            succeeded);
+
+  if (result != NULL || !*succeeded) {
+    return result;
+  }
+
+  // Attempts to allocate, no GC
+  result = satisfy_failed_allocation_helper(word_size,
+                                            context,
+                                            false, /* do_gc */
+                                            false, /* clear_all_soft_refs */
+                                            true,  /* expect_null_mutator_alloc_region */
+                                            succeeded);
+
   if (result != NULL) {
     assert(*succeeded, "sanity");
     return result;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Sep 30 09:07:21 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Sep 30 18:09:40 2015 -0400
@@ -571,7 +571,16 @@
   HeapWord* satisfy_failed_allocation(size_t word_size,
                                       AllocationContext_t context,
                                       bool* succeeded);
+private:
+  // Helper method for satisfy_failed_allocation()
+  HeapWord* satisfy_failed_allocation_helper(size_t word_size,
+                                             AllocationContext_t context,
+                                             bool do_gc,
+                                             bool clear_all_soft_refs,
+                                             bool expect_null_mutator_alloc_region,
+                                             bool* gc_succeeded);
 
+protected:
   // Attempting to expand the heap sufficiently
   // to support an allocation of the given "word_size".  If
   // successful, perform the allocation and return the address of the