United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6935839 excessive marking stack growth during full gcs
6935839 : excessive marking stack growth during full gcs

Details
Type:
Bug
Submit Date:
2010-03-17
Status:
Resolved
Updated Date:
2010-09-24
Project Name:
JDK
Resolved Date:
2010-04-06
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs18
Fixed Versions:
hs18

Related Reports
Backport:
Backport:
Backport:
Backport:
Relates:

Sub Tasks

Description
Nightly test nsk.stress.except.except001.except001 failed on 64-bit windows:

# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=\allocation.inline.hpp:39
#
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 83886080 bytes for GrET in C:\temp\jprt\P1\B\195234\source\src\share\vm\utilities\growableArray.cpp. Out of swap space?
#
#  Internal Error (C:\temp\jprt\P1\B\195234\source\src\share\vm\memory\allocation.inline.hpp:39), pid=178656, tid=168676
#  Error: GrET in C:\temp\jprt\P1\B\195234\source\src\share\vm\utilities\growableArray.cpp
#
# JRE version: 7.0-b85
# Java VM: OpenJDK Client VM (17.0-b09-2010-03-11-195234.nobody.gc-objarray-fastdebug mixed mode windows-x86 )
# An error report file with more information is saved as:
# c:\local\33379.JDK7.NIGHTLY.VM+windows-i586_client_mixed_nsk.stress.testlist\results\ResultDir\except001\hs_err_pid178656.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

                                    

Comments
EVALUATION

ChangeSet=http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/c385bf94cfb8,ChangeRequest=6935839
                                     
2010-03-19
SUGGESTED FIX

When draining the objarray stack/queue, process a single array at a time, instead of all of them.  Par compact should also avoid keeping very large stacks around for the lifetime of the JVM; that will be done as part of 6423256: GC stacks should use a better data structure.
                                     
2010-03-17
EVALUATION

The failing test ran out of c heap.  The additional heap usage is due to deeper marking stacks as a result of the fix for 4396719, which changed processing of object arrays to store in-progress arrays on stacks managed by the jvm instead of using recursion.  The fix was overly aggressive in pushing elements onto the marking stack, thus increasing their depth when marking large arrays.  The problem is compounded in the parallel compacting collector because the various stacks used by each GC worker are kept for the lifetime of the JVM--once a marking stack grows large, the space is never released until the VM exits.  (The serial mark-compact collector allocates and deallocates the stacks at each GC.)  On a many-core machine there will be many gc worker threads, resulting in a lot of unused space.
                                     
2010-03-17
SUGGESTED FIX

diff --git a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
--- a/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
@@ -217,21 +217,21 @@
 void ParCompactionManager::follow_marking_stacks() {
   do {
     // Drain the overflow stack first, to allow stealing from the marking stack.
+    oop obj;
     while (!overflow_stack()->is_empty()) {
       overflow_stack()->pop()->follow_contents(this);
     }
-    oop obj;
     while (marking_stack()->pop_local(obj)) {
       obj->follow_contents(this);
     }
 
+    // Process ObjArrays one at a time to avoid marking stack bloat.
     ObjArrayTask task;
-    while (!_objarray_overflow_stack->is_empty()) {
+    if (!_objarray_overflow_stack->is_empty()) {
       task = _objarray_overflow_stack->pop();
       objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
       k->oop_follow_contents(this, task.obj(), task.index());
-    }
-    while (_objarray_queue.pop_local(task)) {
+    } else if (_objarray_queue.pop_local(task)) {
       objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
       k->oop_follow_contents(this, task.obj(), task.index());
     }
diff --git a/src/share/vm/gc_implementation/shared/markSweep.cpp b/src/share/vm/gc_implementation/shared/markSweep.cpp
--- a/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -111,7 +111,8 @@
       assert (obj->is_gc_marked(), "p must be marked");
       obj->follow_contents();
     }
-    while (!_objarray_stack->is_empty()) {
+    // Process ObjArrays one at a time to avoid marking stack bloat.
+    if (!_objarray_stack->is_empty()) {
       ObjArrayTask task = _objarray_stack->pop();
       objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
       k->oop_follow_contents(task.obj(), task.index());
                                     
2010-03-17



Hardware and Software, Engineered to Work Together