Free ratio based heap shrinking in the parallel collector
Hiroshi Yamauchi
yamauchi at google.com
Thu May 13 23:34:48 UTC 2010
On Thu, May 13, 2010 at 8:52 AM, Jon Masamitsu <jon.masamitsu at oracle.com> wrote:
> Hiroshi,
>
> Looks fine. I only looked at the files where you indicated a change in your
> mail below. If there is more for me to look at, please let me know which
> files.
I don't think there are changes that I haven't indicated.
> I'll get another one of the GC guys here to also review
> the changes.
OK.
>
> I've create a CR for this.
>
> 6952079: With UseParallelScavenge use MinHeapFreeRation/MaxHeapFreeRatio if
> UseAdaptiveSivePolicy is off.
Thanks. I will update my webrev with the bug number.
> What testing have you done? I would expect that UseParallelGC with
> UseAdaptiveSizePolicy turned off to grow and shrink the generations
> in a way similar to UseSerialGC. Can you check that is the case?
My testing is with the use of System.gc() which is used by the main
application behavior pattern that I had described. I checked the
expansion of the heap via the free ratio worked with
-UseAdaptiveSizePolicy and that the shrinkage worked with both
+/-UseAdaptiveSizePolicy on System.gc() (all under UseParallelGC). I
haven't compared it to UseSerialGC.
> I think if you set SurvivorRatio explicitly the survivor spaces will
> be close. You might have to set InitialSurvivorRatio. If you
> set InitialTenuringThreshold and MaxTenuringThreshold to the
> same value, I would expect the promotion rate to be close.
> Promotion rates don't have to be the same but it would remove
> one variable from a comparison. If there are surprises let talk about
> them. Different isn't necessarily wrong.
I assume by 'close' you mean between UseSerialGC and UseParallelGC
with -UseAdaptiveSizePolicy.
I need more elaboration. How would you do the testing described above
(eg how/when to measure them and what to run)?
Hiroshi
>
> Jon
>
> On 05/10/10 16:50, Hiroshi Yamauchi wrote:
>
> Jon,
>
> Thanks for your comments. My new revision is here
>
> http://cr.openjdk.java.net/~hiroshi/webrevs/heapshrink/
>
> My comments are inlined below:
>
>
>
> In parallelScavengeHeap.cpp
>
> In the UseParallelGC collector the initial size (init_size) can be
> significantly larger than the minimum size. If you want to shrink down
> the heap to minimize footprint, do you really want to limit by the
> initial size instead of the minimum size?
>
> 1001 maximum_desired_capacity = MAX2(maximum_desired_capacity,
> init_size);
>
> Similarly here the amount of used data could be very small and
> setting the floor at the initial size may not be what you
> want.
>
> 1034 minimum_desired_capacity = MAX2(minimum_desired_capacity,
> init_size);
>
>
> I changed the code so that it uses the min size instead of the init size.
>
>
>
> In psYoungGen.cpp you guard output with PrintGC only. In similar
> cases this type of output is guarded with Verbose also. Does this
> output as is get printed in the middle of the usual
> -verbosegc (also known as PrintGC) line?
>
> 1000 if (PrintGC) {
> 1001 gclog_or_tty->print_cr(" Resizing young gen. expand_bytes=%d,%d",
> 1002 eden_expand_bytes, survivor_expand_bytes);
> 1003 gclog_or_tty->print("BEFORE: Young Gen: ");
> 1004 gclog_or_tty->print("eden capacity : " SIZE_FORMAT ", ",
> 1005 eden_space()->capacity_in_bytes());
> 1006 gclog_or_tty->print("eden used : " SIZE_FORMAT ", " ,
> 1007 eden_space()->used_in_bytes());
> 1008 gclog_or_tty->print("survivor capacity : " SIZE_FORMAT ", ",
> 1009 from_space()->capacity_in_bytes());
> 1010 gclog_or_tty->print_cr("survivor used : " SIZE_FORMAT ", " ,
> 1011 from_space()->used_in_bytes());
> 1012 }
>
>
> I added Verbose to the guard. And yes, the output show up in the
> middle of PrintGC line.
>
>
>
> In psOldGen.cpp you could try to expand up to max_gen_size
> instead of returning?
>
> 501 void PSOldGen::try_to_expand_by(size_t expand_bytes) {
> 502 if (expand_bytes < MinHeapDeltaBytes ||
> 503 capacity_in_bytes() + expand_bytes > max_gen_size()) {
> 504 return;
>
> Additionally PSOldGen::expand() chooses to use MinHeapDeltaBytes
> as the minimum expansion size (in the sense that sizes for expansion
> are round up to MinHeapDeltaBytes). You would rather not expand
> for less than MinHeapDeltaBytes? I'll admit that there maybe some
> inconsistencies in the way MinHeapDeltaBytes is used. Just checking
> that this is what you want to do.
>
> Again, seems to me that you want to shrink down to the minimum
> generation size as opposed to the initial size.
>
> 523 void PSOldGen::try_to_shrink_by(size_t shrink_bytes) {
> 524 if (shrink_bytes < MinHeapDeltaBytes ||
> 525 capacity_in_bytes() - shrink_bytes < init_gen_size()) {
> 526 return;
> 527 }
>
>
> Now I have:
>
> 502 if (capacity_in_bytes() + expand_bytes > max_gen_size()) {
> 503 expand_bytes = max_gen_size() - capacity_in_bytes();
> 504 }
>
> and likewise for try_to_shrink_by().
>
> 1. It allows the subsequent code (eg expand()) to round up the size <
> MinHeapDeltaBytes.
> 2. It rounds down the size that goes past the max/min gen size so that
> the heap is expanded/shrunk to the max/min.
>
>
>
> In globals.hpp. We may want this feature implemented in other
> collectors at some point - G1 comes to mind. I'd drop the leading
> PS on the flag so that it is ResizeByFreeRatioWithSystemGC.
>
> 3079 product(bool, PSResizeByFreeRatioWithSystemGC,
> false, \
> 3080 "Resize the heap by free ratio in System.gc()
> " \
> 3081 "under UseParallelGC")
>
>
>
> Done.
>
> Hiroshi
>
More information about the hotspot-gc-dev
mailing list