ParallelGC issue: collector does only Full GC

Srinivas Ramakrishna ysr1729 at gmail.com
Thu Oct 24 10:50:57 PDT 2013


The email I had in mind was this one:-

http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2013-May/007092.html

It appears as though the attachments I had sent were scrubbed, so folks on
the list may not have seen the
attachments. I'll see if I can dig them up and reconstruct it again. I also
couldn't find the email in which I promised to
send the fix I had in mind, although that can pretty much be constructed
from the email description.

I'll see if I can find the relevant attachments and upload them into a bug
report of this. I have only been
half-following this exchange, so it's possible that it's somewhat
tangentially related, but definitely
related to the prediction model for how much gets promoted.

-- ramki



On Thu, Oct 24, 2013 at 10:12 AM, Srinivas Ramakrishna <ysr1729 at gmail.com>wrote:

> I had called in this bug earlier this year -- the model can be easily
> improved. I will try and dig up the email in which I had described the issue
> and the suggested fix.
>
> -- ramki
>
>
> On Thu, Oct 24, 2013 at 5:00 AM, charlie hunt <charlesjhunt at gmail.com>wrote:
>
>> I did a little experimenting with this ... I think Jon's hypothesis is
>> right.
>>
>> I first reproduced the behavior as described by Andreas.  Then, I set
>> -XX:PromotedPadding=1 in the case where NewSize/MaxNewSize is at 1800m.
>> That eliminated the issue Andreas observed at 1800m. But, as I suspected
>> the threshold at which the change in behavior merely changed at a higher
>> sizing of young gen. It now occurs at about 2300m, up from 1800m.
>>
>> So, it does look like there is an issue with the prediction model since
>> PromotedPadding can influence the prediction model.
>>
>> The prediction model code does not look trivial, as I'm sure Jon knows. ;)
>>
>> hths,
>>
>> charlie ...
>>
>>
>>
>>
>> On Wed, Oct 23, 2013 at 3:03 AM, Andreas Müller <
>> Andreas.Mueller at mgm-tp.com> wrote:
>>
>>> Hi Jon,
>>>
>>> thanks for the hint to Java 8.
>>> I have verified with jdk1.8.0-ea-b112 (from October 17): behavior
>>> remains as described
>>>
>>> Best regards
>>> Andreas
>>>
>>> ----------------------------------------------------------------------
>>>
>>> Date: Mon, 21 Oct 2013 15:29:10 -0700
>>> From: Jon Masamitsu <jon.masamitsu at oracle.com>
>>> Subject: Re: ParallelGC issue: collector does only Full GC by default
>>>         and     above NewSize=1800m
>>> To: hotspot-gc-use at openjdk.java.net
>>> Message-ID: <5265AAB6.1050700 at oracle.com>
>>> Content-Type: text/plain; charset="iso-8859-1"
>>>
>>> Andreas,
>>>
>>> There was a bug fixed in jdk8 that had similar symptoms.  If you can try
>>> a jdk8 build that might tell us something.
>>>
>>> If jdk8 doesn't help it's likely that the prediction model thinks that
>>> there is not enough
>>> free space in the old gen to support a young collection.   We've been
>>> working on 7098155 to
>>> fix that.
>>>
>>> Jon
>>>
>>>
>>> On 10/21/2013 10:09 AM, Andreas M?ller wrote:
>>> > Hi all,
>>> >
>>> > while experimenting a bit with different Garbage Collectors and
>>> > applying them to my homegrown micro benchmarks I stumbled into the
>>> following problem:
>>> > I run the below sample with the following command line (using Java
>>> 1.7.0_40 on Windows and probably others):
>>> > java -Xms6g -Xmx6g -XX:+UseParallelGC -
>>> > de.am.gc.benchmarks.MixedRandomList 100 8 12500000
>>> >
>>> > The Default and proven ParallelGC collector does mostly Full GCs and
>>> shows only poor out-of-the-box performance, more than a factor 10 lower
>>> than the ParNew collector.
>>> > More tests adding the -XX:NewSize=<xyz>m and -XX:MaxNewSize=<xyz>m
>>> reveal that the problem occurs as soon as the NewSize rises beyond 1800m
>>> which it obviously does by default.
>>> > Below that threshold ParallelGC performance is similar to ParNewGC (in
>>> the range of 7500 MB/s on my i7-2500MHz notebook), but at NewSize=2000m is
>>> as low as 600 MB/s.
>>> >
>>> > Any ideas why this might happen?
>>> >
>>> > Note that the sample is constructed such that the live heap is always
>>> around 3GB. If any I would expect a problem only at around NewSize=3GB,
>>> when Old Gen shrinks to less than the live heap size. As a matter of fact,
>>> ParNewGC can do >7000 MB/s from NewSize=400m to NewSize=3500m with little
>>> variation around a maximum of 7600 MB/s at NewSize=2000m.
>>> >
>>> > I also provide source, gc.log and a plot of the NewSize dependency to
>>> anyone interested in that problem.
>>> >
>>> > Regards
>>> > Andreas
>>> >
>>> > -------------------------------------------------------MixedRandomList
>>> > .java-----------------------------------------------------------------
>>> > -------------------------------------------------------
>>> > package de.am.gc.benchmarks;
>>> >
>>> > import java.util.ArrayList;
>>> > import java.util.List;
>>> >
>>> > /**
>>> > * GC benchmark producing a mix of lifetime=0 and lifetime>0 objects
>>> which are kept in randomly updated lists.
>>> >   *
>>> >   * @author Andreas Mueller
>>> > */
>>> > public class MixedRandomList {
>>> >      private static final int DEFAULT_NUMBEROFTHREADS=1;
>>> >      // object size in bytes
>>> >      private static final int DEFAULT_OBJECTSIZE=100;
>>> >
>>> >      private static int numberOfThreads=DEFAULT_NUMBEROFTHREADS;
>>> >      private static int objectSize=DEFAULT_OBJECTSIZE;
>>> >      // number of objects to fill half of the available memory with
>>> (permanent) live objects
>>> >      private static long numLive =
>>> > (Runtime.getRuntime().maxMemory()/objectSize/5);
>>> >
>>> >      /**
>>> >       * @param args the command line arguments
>>> >       */
>>> >      public static void main(String[] args) {
>>> >          if( args.length>0 ) {
>>> >              // first, optional argument is the size of the objects
>>> >              objectSize = Integer.parseInt(args[0]);
>>> >              // second, optional argument is the number of live objects
>>> >              if( args.length>1 ) {
>>> >                  numberOfThreads = Integer.parseInt(args[1]);
>>> >                  // third, optional argument is the number of live
>>> objects
>>> >                  if( args.length>2 ) {
>>> >                      numLive = Long.parseLong(args[2]);
>>> >                  }
>>> >              }
>>> >          }
>>> >          for( int i=0; i<numberOfThreads; i++ ) {
>>> >              // run several GarbageProducer threads, each with its own
>>> mix of lifetime=0 and higher lifetime objects
>>> >              new Thread(new
>>> GarbageProducer((int)Math.pow(50.0,(double)(i+1)),
>>> numLive/numberOfThreads)).start();
>>> >          }
>>> >          try {
>>> >              Thread.sleep(1200000);
>>> >          } catch( InterruptedException iexc) {
>>> >              iexc.printStackTrace();
>>> >          }
>>> >          System.exit(0);
>>> >      }
>>> >
>>> >      private static char[] getCharArray(int length) {
>>> >          char[] retVal = new char[length];
>>> >          for(int i=0; i<length; i++ ) {
>>> >              retVal[i] = 'a';
>>> >          }
>>> >          return retVal;
>>> >      }
>>> >
>>> >      public static class GarbageProducer implements Runnable {
>>> >
>>> >          // the fraction of newly created objects that do not become
>>> garbage immediately but are stored in the liveList
>>> >          int fractionLive;
>>> >          // the size of the liveList
>>> >          long myNumLive;
>>> >
>>> >          /**
>>> >           * Each GarbageProducer creates objects that become garbage
>>> immediately (lifetime=0) and
>>> >           * objects that become garbage only after a lifetime>0 which
>>> is distributed about an average lifetime.
>>> >           * This average lifetime is a function of fractionLive and
>>> numLive
>>> >           *
>>> >           * @param fractionLive
>>> >           * @param numLive
>>> >           */
>>> >          public GarbageProducer(int fractionLive, long numLive) {
>>> >              this.fractionLive = fractionLive;
>>> >              this.myNumLive = numLive;
>>> >          }
>>> >
>>> >          @Override
>>> >          public void run() {
>>> >              int osize = objectSize;
>>> >              char[] chars = getCharArray(objectSize);
>>> >              List<String> liveList = new
>>> ArrayList<String>((int)myNumLive);
>>> >              // initially, the lifeList is filled
>>> >              for(int i=0; i<myNumLive; i++) {
>>> >                  liveList.add(new String(chars));
>>> >              }
>>> >              while(true) {
>>> >                  // create the majority of objects as garbage
>>> >                  for(int i=0; i<fractionLive; i++) {
>>> >                      String garbageObject = new String(chars);
>>> >                  }
>>> >                  // keep the fraction of objects live by placing them
>>> in the list (at a random index)
>>> >                  int index = (int)(Math.random()*myNumLive);
>>> >                  liveList.set(index, new String(chars));
>>> >              }
>>> >          }
>>> >      }
>>> > }
>>> > ----------------------------------------------------------------------
>>> > ----------------------------------------------------------------------
>>> > ---------------------------------------------------------------------
>>> >
>>> > Andreas M?ller
>>> >
>>> > mgm technology partners GmbH
>>> > Frankfurter Ring 105a
>>> > 80807 M?nchen
>>> > Tel. +49 (89) 35 86 80-633
>>> > Fax +49 (89) 35 86 80-288
>>> > E-Mail Andreas.Mueller at mgm-tp.com<mailto:Andreas.Mueller at mgm-tp.com>
>>> > Innovation Implemented.
>>> > Sitz der Gesellschaft: M?nchen
>>> > Gesch?ftsf?hrer: Hamarz Mehmanesh
>>> > Handelsregister: AG M?nchen HRB 105068
>>> >
>>> >
>>> >
>>> >
>>> > _______________________________________________
>>> > hotspot-gc-use mailing list
>>> > hotspot-gc-use at openjdk.java.net
>>> > http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
>>>
>>> -------------- next part --------------
>>> An HTML attachment was scrubbed...
>>> URL:
>>> http://mail.openjdk.java.net/pipermail/hotspot-gc-use/attachments/20131021/62d044c7/attachment-0001.html
>>>
>>> ------------------------------
>>>
>>> _______________________________________________
>>> hotspot-gc-use mailing list
>>> hotspot-gc-use at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
>>>
>>>
>>> End of hotspot-gc-use Digest, Vol 68, Issue 5
>>> *********************************************
>>> _______________________________________________
>>> hotspot-gc-use mailing list
>>> hotspot-gc-use at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
>>>
>>
>>
>> _______________________________________________
>> hotspot-gc-use mailing list
>> hotspot-gc-use at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/hotspot-gc-use
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-gc-use/attachments/20131024/f2de300a/attachment-0001.html 


More information about the hotspot-gc-use mailing list