United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6724367 par compact could clear less young gen summary data
JDK-6724367 : par compact could clear less young gen summary data

Details
Type:
Enhancement
Submit Date:
2008-07-10
Status:
Closed
Updated Date:
2010-04-28
Project Name:
JDK
Resolved Date:
2010-04-28
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
hs14 (b03)

Related Reports
Backport:
Backport:

Sub Tasks

Description
The par compaction summary phase makes two passes over each Space in the GC heap.  The first pass updates the data as if each Space were to be compacted completely (i.e., leaving no dead space) into itself.  This is used to determine how much data is live in the Space and allows a dense prefix to be computed where applicable (the old gen and the perm gen).  The second pass then computes the final destinations.  Live data from the young gen Spaces is normally copied to the old gen, assuming it will fit.  For young gen spaces that fit into the old gen, certain fields of the summary data must be cleared.  More data than necessary is being cleared.

                                    

Comments
EVALUATION

The problem occurs only for Spaces in the young gen that are non-empty at the start of a full gc.  Since -XX:+ScavengeBeforeFullGC is enabled by default, full GCs occur after a scavenge which normally empties eden.  So 95% of the time, only To space contains data while Eden and From space are empty.

For each non-empty space in the young gen, the summary phase currently clears data from space->bottom() to space->top() (the top() value before the start of the full gc).  However, it is only necessary to clear from space->bottom() to the the "new top" for the space, where "new top" refers to the value computed by the first pass of the summary phase (which computes values to compact the space completely into itself).  The "new top" is usually significantly less than space->top(), so less clearing can be done.
                                     
2008-07-10
SUGGESTED FIX

--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -1635,7 +1635,7 @@
     const size_t live = pointer_delta(_space_info[id].new_top(),
                                       space->bottom());
     const size_t available = pointer_delta(target_space_end, *new_top_addr);
-    if (live <= available) {
+    if (live > 0 && live <= available) {
       // All the live data will fit.
       if (TraceParallelOldGCSummaryPhase) {
         tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
@@ -1645,16 +1645,18 @@
                               space->bottom(), space->top(),
                               new_top_addr);
 
-      // Reset the new_top value for the space.
-      _space_info[id].set_new_top(space->bottom());
-
       // Clear the source_chunk field for each chunk in the space.
+      HeapWord* const new_top = _space_info[id].new_top();
+      HeapWord* const clear_end = _summary_data.chunk_align_up(new_top);
       ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom());
-      ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1);
-      while (beg_chunk <= end_chunk) {
+      ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end);
+      while (beg_chunk < end_chunk) {
         beg_chunk->set_source_chunk(0);
         ++beg_chunk;
       }
+
+      // Reset the new_top value for the space.
+      _space_info[id].set_new_top(space->bottom());
     }
   }
                                     
2008-07-10
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/2214b226b7f0
                                     
2008-07-12



Hardware and Software, Engineered to Work Together