JEP 248: Make G1 the Default Garbage Collector
charlie hunt
charlie.hunt at oracle.com
Tue Jun 2 12:29:32 UTC 2015
Hi Erik,
Let’s pull out a couple of your questions here and see I can offer some answers.
> I do not see why this (latency requirement uncertainty) specifically
> would be a problem for this particular transition into using G1 more instead of
> ParallelGC. Let’s focus only on the narrow scope of transitioning
> application contexts from ParallelGC to G1 only for “larger” heaps. Is
> there any application context then where G1 has worse latency than
> ParallelGC?
My observations have been that it is not a question of the size of the Java heap, although folks often refer to it in this way. It is more about the combination of the amount of live data, the amount of available space between the live data and the Java heap and the object lifetimes. There are Java apps out there where if Parallel GC is configured in a way (either by mere accident the defaults hit this situation, which would be unusual, or by manually tuning GC), Parallel GC’s young generation is configured in a way that old generation collection can be avoided, many of objects allocated die young, (i.e. there is not a humongous amount of objects sloshing around between survivor spaces, and few, if any are promoted to old gen), Parallel GC will likely offer lower latency than G1. Again, to reiterate, to do this with Parallel GC will likely require a GC tuning effort. Yet there may be an app, or some small number of apps that Parallel GC with its JVM defaults could fit what I just described. But, then again, the context of this JEP is before GC tuning.
To up level this a bit, with a given GC, it is generally accepted that as one performance attribute is emphasized, (throughput, latency and memory footprint), there is a sacrifice in one or two of the others. I think you are kind of saying this here too. But, I thought it was worth mentioning specifically. I’ll come back to this a bit later.
> Another concern Jenny mentioned where G1 could perform worse was JVM start
> up time. Again, I have a hard time imagining a /server application/ with
> an explicitly specified “large” heap where anyone would care too much
> about this. Am I wrong?
If we are talking about the difference in time to start the JVM relative to the time it takes to generally initiate a Java app with a large Java heap, then yes, I don’t think it would be much of a concern. This is not to be confused with whether someone is not concerned with the time it takes to initiate an application with a large Java heap taking a long time. That is a different story. ;-)
> And here G1 was designed, correct me if
> I’m wrong, to be not necessarily the best at anything, but pretty good at
> everything (latencies, performance and memory footprints). This sounds to
> me like a reasonable choice for default application contexts where it’s
> not known if the user cares about this or that QoS.
This is pretty much the conclusion that I have arrived at. IMO, G1 due to its ergonomics offers a larger population of applications a “happy medium” of tradeoffs between the three performance attributes than Parallel GC in the absence of further tuning.
thanks,
charlie
> On Jun 1, 2015, at 6:16 PM, Erik Österlund <erik.osterlund at lnu.se> wrote:
>
> Hi Charlie,
>
> Den 01/06/15 22:51 skrev charlie hunt <charlie.hunt at oracle.com>:
>
>> Hi Erik,
>>
>> HotSpot does some of this ergonomics today for both GC and JIT compiler
>> in cases where the JVM sees less than 2 GB of RAM and the OS it is
>> running on. These decisions are based on what is called a “server class
>> machine”. A “server class machine” as of JDK 6u18 is defined as a system
>> that has 2 GB or more of RAM, two or more hardware threads. There are
>> other cases for a given hardware platform, and if it is a 32-bit JVM, the
>> collector (and JIT compiler) ergonomically selected may also differ from
>> other configurations.
>>
>> AFAIK, the JEP is proposing to change the default GC in configurations
>> where the default GC is Parallel GC to using G1 as the default.
>
> I think the fact that these ergonomics tricks are already around only
> motivates the approach further as it is in line with the current
> philosophy that if the user is not explicit about things, then the runtime
> can and will guess a bit and try to aim for some kind of middle ground
> solutions that are pretty good but not necessarily the best at everything
> (like G1 was designed to be). If the guess doesn’t cut it because it turns
> out that only a single QoS was important, like for instance performance
> over everything else, then maybe the user should have said so. ;)
>
>> The challenge with what you are describing is that the best GC cannot
>> always be ergonomically selected by the JVM without some input from the
>> user, i.e. GC doesn’t know if any GC pauses greater than 200 ms are
>> acceptable regardless of Java heap size, number of hardware threads, etc.
>
> I do not see why this (latency requirement uncertainty) specifically would
> be a problem for this particular transition into using G1 more instead of
> ParallelGC. Let’s focus only on the narrow scope of transitioning
> application contexts from ParallelGC to G1 only for “larger" heaps. Is
> there any application context then where G1 has worse latency than
> ParallelGC? I assume not. So the only visible effect such a change would
> bring is improved latencies if anything. And the whole mega-low-latency
> discussion where G1 doesn’t cut it is quite irrelevant for this change as
> well as those people affected are already not satisfied with ParallelGC
> that wouldn’t cut it either, and hence specify something explicitly.
>
> Another concern Jenny mentioned where G1 could perform worse was JVM start
> up time. Again, I have a hard time imagining a /server application/ with
> an explicitly specified “large" heap where anyone would care too much
> about this. Am I wrong?
>
> What is left to annoy people with such a change then (apart from bugs)
> with latency not being one of them, is resource trade offs in terms of
> memory footprints and performance. And here G1 was designed, correct me if
> I’m wrong, to be not necessarily the best at anything, but pretty good at
> everything (latencies, performance and memory footprints). This sounds to
> me like a reasonable choice for default application contexts where it’s
> not known if the user cares about this or that QoS. And with the
> observation from Jenny that even performance seems to actually be better
> than ParallelGC for application contexts with large heaps, and the
> knowledge that latency is in general more important then, does it not make
> sense to choose G1 at least for those application contexts?
>
> Of course this is just a suggestion based on generalizations. Just thought
> it’s an interesting middle ground worth considering to instead of only
> considering either changing all or none of the default server application
> contexts, to only change the subset where we think it is least likely to
> annoy people, and then as G1 continues to improve and one size starts
> fitting all, expand that subset in a smoother transition.
>
> Thanks,
> /Erik
>
>>
>> thanks,
>>
>> charlie
>>
>>> On Jun 1, 2015, at 2:53 PM, Erik Österlund <erik.osterlund at lnu.se>
>>> wrote:
>>>
>>> Hi all,
>>>
>>> Does there have to be a single default one-size-fits-all GC algorithm
>>> for
>>> users to rely on? Or could we allow multiple algorithms and explicitly
>>> document that unless a GC is picked, the runtime is free to pick
>>> whatever
>>> it believes is better? This could have multiple benefits.
>>>
>>> 1. This could make such a similar change easier in the future as
>>> everyone
>>> will already be aware that if they really rely on the properties of a
>>> specific GC algorithm, then they should choose that GC explicitly and
>>> not
>>> rely on defaults not changing; there are no guarantees that defaults
>>> will
>>> not change.
>>>
>>> 2. Obviously there has been a long discussion in this thread which GC is
>>> better in which context, and it seems like right now one size does not
>>> fit
>>> all. The user that relied on the defaults might not be so aware of these
>>> specifics. Therefore we might do them a big favour of attempting to
>>> make a
>>> guess for them to work out-of-the-box, which is pretty neat.
>>>
>>> 3. This approach allows deploying G1 not everywhere, but where we guess
>>> it
>>> performs pretty well. This means it will run in fewer JVM contexts and
>>> hence pose less risk than deploying it to be used for all contexts,
>>> making
>>> the transition smoother.
>>>
>>> One idea could be to first determine valid GC variants given the
>>> supplied
>>> flags (GC-specific flags imply use of that GC), and then among the valid
>>> GCs left, ³guess² which algorithm is better based on the other general
>>> parameters, such as e.g. heap size (and maybe target latency)? Could for
>>> instance pick ParallelGC for small heaps, G1 for larger heaps and CMS
>>> for
>>> ridiculously large heaps or cases when extremely low latency is wanted?
>>>
>>> My reasoning is based on two assumptions: 1) changing the defaults would
>>> target the users that don¹t know what¹s best for them, 2) one size does
>>> not fit all. If these assumption are wrong, then this is a bad idea.
>>>
>>> Thanks,
>>> /Erik
>>>
>>>
>>>
>>> Den 01/06/15 20:53 skrev charlie hunt <charlie.hunt at oracle.com>:
>>>
>>>> Hi Jenny,
>>>>
>>>> A couple questions and comments below.
>>>>
>>>> thanks,
>>>>
>>>> charlie
>>>>
>>>>> On Jun 1, 2015, at 1:28 PM, Yu Zhang <yu.zhang at oracle.com> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I have done some performance comparison g1/cms/parallelgc internally
>>>>> at
>>>>> Oracle. I would like to post my observations here to get some
>>>>> feedback,
>>>>> as I have limited benchmarks and hardware. These are out of box
>>>>> performance.
>>>>>
>>>>> Memory footprint/startup:
>>>>> g1 has bigger memory footprint and longer start up time. The overhead
>>>>> comes from more gc threads, and internal data structures to keep track
>>>>> of remember set.
>>>>
>>>> This is the memory footprint of the JVM itself when using the same size
>>>> Java heap, right?
>>>>
>>>> I don¹t recall if it has been your observation? One observation I have
>>>> had with G1 is that it tends to be able to operate within tolerable
>>>> throughput and latency with a smaller Java heap than with Parallel GC.
>>>> I
>>>> have seen cases where G1 may not use the entire Java heap because it
>>>> was
>>>> able to keep enough free regions available yet still meet pause time
>>>> goals. But, Parallel GC always use the entire Java heap, and once its
>>>> occupancy reach capacity, it would GC. So they are cases where between
>>>> the JVM¹s footprint overhead, and taking into account the amount of
>>>> Java
>>>> heap required, G1 may actually require less memory.
>>>>
>>>>>
>>>>> g1 vs parallelgc:
>>>>> If the workload involves young gc only, g1 could be slightly slower.
>>>>> Also g1 can consume more cpu, which might slow down the benchmark if
>>>>> SUT
>>>>> is cpu saturated.
>>>>>
>>>>> If there are promotions from young to old gen and leads to full gc
>>>>> with
>>>>> parallelgc, for smaller heap, parallel full gc can finish within some
>>>>> range of pause time, still out performs g1. But for bigger heap, g1
>>>>> mixed gc can clean the heap with pause times a fraction of parallel
>>>>> full
>>>>> gc time, so improve both throughput and response time. Extreme cases
>>>>> are big data workloads(for example ycsb) with 100g heap.
>>>>
>>>> I think what you are saying here is that it looks like if one can tune
>>>> Parallel GC such that you can avoid a lengthy collection of old
>>>> generation, or the live occupancy of old gen is small enough that the
>>>> time to collect is small enough to be tolerated, then Parallel GC will
>>>> offer a better experience.
>>>>
>>>> However, if the live data in old generation at the time of its
>>>> collection
>>>> is large enough such that the time it takes to collect it exceeds a
>>>> tolerable pause time, then G1 will offer a better experience.
>>>>
>>>> Would also say that G1 offers a better experience in the presences of
>>>> (wide) swings in object allocation rates since there would likely be a
>>>> larger number of promotions during the allocation spikes? In other
>>>> words, G1 may offer more predictable pauses.
>>>>
>>>>>
>>>>> g1 vs cms:
>>>>> I will focus on response time type of workloads.
>>>>> Ben mentioned
>>>>>
>>>>> "Having said that, there is definitely a decent-sized class of systems
>>>>> (not just in finance) that cannot really tolerate any more than about
>>>>> 10-15ms of STW. So, what usually happens is that they live with the
>>>>> young collections, use CMS and tune out the CMFs as best they can (by
>>>>> clustering, rolling restart, etc, etc). I don't see any possibility of
>>>>> G1 becoming a viable solution for those systems any time soon."
>>>>>
>>>>> Can you give more details, like what is the live data set size, how
>>>>> big
>>>>> is the heap, etc? I did some cache tests (Oracle coherence) to
>>>>> compare
>>>>> cms vs g1. g1 is better than cms when there are fragmentations. If you
>>>>> tune cms well to have little fragmentation, then g1 is behind cms.
>>>>> But
>>>>> for those cases, they have to tune CMS very well, changing default to
>>>>> g1
>>>>> won't impact them.
>>>>>
>>>>> For big data kind of workloads (ycsb, spark in memory computing), g1
>>>>> is
>>>>> much better than cms.
>>>>>
>>>>> Thanks,
>>>>> Jenny
>>>>>
>>>>> On 6/1/2015 10:06 AM, Ben Evans wrote:
>>>>>> Hi Vitaly,
>>>>>>
>>>>>>>> Instead, G1 is now being talked of as a replacement for the default
>>>>>>>> collector. If that's the case, then I think we need to acknowledge
>>>>>>>> it,
>>>>>>>> and have a conversation about where G1 is actually supposed to be
>>>>>>>> used. Are we saying we want a "reasonably high throughput with
>>>>>>>> reduced
>>>>>>>> STW, but not low pause time" collector? If we are, that's fine, but
>>>>>>>> that's not where we started.
>>>>>>> That's a fair point, and one I'd be interesting in hearing an answer
>>>>>>> to as
>>>>>>> well. FWIW, the only GC I know of that's actually used in low
>>>>>>> latency
>>>>>>> systems is Azul's C4, so I'm not even sure Oracle is trying to
>>>>>>> target
>>>>>>> the
>>>>>>> same use cases. So when we talk about "low latency" GCs, we should
>>>>>>> probably
>>>>>>> also be clear on what "low" actually means.
>>>>>> Well, when I started playing with them, "low latency" meant a
>>>>>> sub-10-ms transaction time with 100ms STW as acceptable, if not
>>>>>> ideal.
>>>>>>
>>>>>> These days, the same sort of system needs a sub 500us transaction
>>>>>> time, and ideally no GC pause at all. But that leads to Zing, or
>>>>>> non-JVM solutions, and I think takes us too far into a specialised
>>>>>> use
>>>>>> case.
>>>>>>
>>>>>> Having said that, there is definitely a decent-sized class of systems
>>>>>> (not just in finance) that cannot really tolerate any more than about
>>>>>> 10-15ms of STW. So, what usually happens is that they live with the
>>>>>> young collections, use CMS and tune out the CMFs as best they can (by
>>>>>> clustering, rolling restart, etc, etc). I don't see any possibility
>>>>>> of
>>>>>> G1 becoming a viable solution for those systems any time soon.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Ben
>>>>>
>>>>
>>>
>>
>
More information about the hotspot-dev
mailing list