--- old/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp 2010-03-10 14:49:38.000000000 -0800 +++ new/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp 2010-03-10 14:49:38.000000000 -0800 @@ -163,6 +163,9 @@ set_space_boundaries(eden_size, survivor_size); space_invariants(); + _init_survivor_size = survivor_size; + _init_eden_size = eden_size; + if (UsePerfData) { _eden_counters->update_capacity(); _from_counters->update_capacity(); @@ -949,3 +952,76 @@ to_space()->set_top_for_allocations(); } #endif + +void PSYoungGen::try_to_shrink_by(size_t shrink_bytes) { + size_t free_bytes = capacity_in_bytes() - used_in_bytes(); + if (free_bytes == 0) { + // cannot shrink + return; + } + size_t eden_free_bytes = eden_space()->capacity_in_bytes() - eden_space()->used_in_bytes(); + size_t survivor_free_bytes = from_space()->capacity_in_bytes() - from_space()->used_in_bytes(); + size_t eden_shrink_bytes = + (size_t) (shrink_bytes * ((double) eden_free_bytes / free_bytes)); + size_t survivor_shrink_bytes = + (size_t) (shrink_bytes * ((double) survivor_free_bytes / free_bytes)); + + // Don't shrink unless it's significant + if (eden_shrink_bytes < MinHeapDeltaBytes) { + eden_shrink_bytes = 0; + } + if (survivor_shrink_bytes < MinHeapDeltaBytes) { + survivor_shrink_bytes = 0; + } + + if (eden_shrink_bytes == 0 && survivor_shrink_bytes == 0) { + return; // no change, so return now + } + + size_t eden_desired_capacity = + eden_space()->capacity_in_bytes() - eden_shrink_bytes; + eden_desired_capacity = MAX2(eden_desired_capacity, _init_eden_size); + assert(eden_space()->used_in_bytes() <= eden_desired_capacity, "sanity check"); + eden_desired_capacity = align_size_down(eden_desired_capacity, + virtual_space()->alignment()); + + size_t survivor_desired_capacity = + from_space()->capacity_in_bytes() - survivor_shrink_bytes; + survivor_desired_capacity = MAX2(survivor_desired_capacity, _init_survivor_size); + assert(from_space()->used_in_bytes() <= survivor_desired_capacity, "sanity check"); + survivor_desired_capacity = align_size_down(survivor_desired_capacity, + virtual_space()->alignment()); + + if (eden_desired_capacity == eden_space()->capacity_in_bytes() + && survivor_desired_capacity == from_space()->capacity_in_bytes()) { + return; // no change, so return now + } + + if (PrintGC) { + gclog_or_tty->print_cr(" Resizing young gen. shrink_bytes=%d,%d", + eden_shrink_bytes, survivor_shrink_bytes); + gclog_or_tty->print("BEFORE: Young Gen: "); + gclog_or_tty->print("eden capacity : " SIZE_FORMAT ", ", + eden_space()->capacity_in_bytes()); + gclog_or_tty->print("eden used : " SIZE_FORMAT ", " , + eden_space()->used_in_bytes()); + gclog_or_tty->print("survivor capacity : " SIZE_FORMAT ", ", + from_space()->capacity_in_bytes()); + gclog_or_tty->print_cr("survivor used : " SIZE_FORMAT ", " , + from_space()->used_in_bytes()); + } + + resize(eden_desired_capacity, survivor_desired_capacity); + + if (PrintGC) { + gclog_or_tty->print("AFTER: Young Gen: "); + gclog_or_tty->print("eden capacity : " SIZE_FORMAT ", ", + eden_space()->capacity_in_bytes()); + gclog_or_tty->print("eden used : " SIZE_FORMAT ", " , + eden_space()->used_in_bytes()); + gclog_or_tty->print("survivor capacity : " SIZE_FORMAT ", ", + from_space()->capacity_in_bytes()); + gclog_or_tty->print_cr("survivor used : " SIZE_FORMAT ", " , + from_space()->used_in_bytes()); + } +}