X

A Work in Progress

When you execute "java ..." you get some number of garbage collection (GC) threads. If you want to know how many GC threads, you can execute java -XX:+PrintFlagsFinal -version and look for ParallelGCThreads in the output (of which there will be plenty). You will find something like uintx ParallelGCThreads := 23 {product} If the number of GC threads you see looks way too big to you, this note may be of some interest. That number of GC threads is some fraction of the number...

Thursday, September 29, 2016 | Java | Read More

The Unspoken - The Why of GC Ergonomics

Do you use GC ergonomics, -XX:+UseAdaptiveSizePolicy, with the UseParallelGC collector? The jist of GC ergonomics for that collector is that it tries to grow or shrink the heap to meet a specified goal. The goals that you can choose are maximum pause time and/or throughput. Don't get too excited there. I'm speaking about UseParallelGC (the throughput collector) so there are definite limits to what pausegoals can be achieved. When you say out loud "I don't care about pause...

Friday, June 28, 2013 | Java | Read More

The Unspoken - Application Times

Sometimes it is interesting to know how long your application runs between garbage collections. That can be calculated from the GC logs but a convenient way to see that information is through the command line flags -XX:+PrintGCApplicationStoppedTime and -XX:+PrintGCApplicationConcurrentTime. Adding these to your command line produces output such as this. Application time: 0.2863875 secondsTotal time for which application threads were stopped: 0.0225087 secondsApplication...

Thursday, April 18, 2013 | Java | Read More

The Unspoken - CMS and PrintGCDetails

What follows is an example of the GC logging output with CMS (UseConcMarkSweepGC) and PrintGCDetails plus some explanation of the output. The "CMS-initial-mark" indicates the start of a CMS concurrent collection. [GC [1 CMS-initial-mark: 463236K(515960K)] 464178K(522488K), 0.0018216 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 463236K above is the space occupied by objects in the old (CMS) generation at the start of the collection. Not all those objects are necessarily...

Wednesday, February 13, 2013 | Java | Read More

The Unspoken - Phases of CMS

CMS (-XX:+UseConcMarkSweepGC) or the concurrent mark sweep GC could have been called the mostly concurrent mark sweep GC and here's why. These are the phases of a CMS concurrent collection. 1. Initial mark. This is the the start of CMS collection. This is a stop-the-world phase. All the applications threads are stopped and CMS scans the application threads (e.g. the thread stacks) for object references. 2. Concurrent mark. This is a concurrent phase. CMS restarts all the...

Monday, February 11, 2013 | Java | Read More

Really? iCMS? Really?

When I use the term iCMS, I'm referring to the incremental mode of CMS (-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode). This is a mode of CMS where the concurrent phases (concurrent marking and concurrent sweeping) are run in short increments (does some work, yields and sleeps for a while, then runs again). It was implemented in CMS primarily for use on platforms with a single hardware thread. The concurrent phases are typically long (think seconds and not milliseconds).If...

Tuesday, November 1, 2011 | Java | Read More

Help for the NUMA Weary

When you think about running on a machine with a non-uniform memory architecture (NUMA), do you think, "Cool, some memory is really close"? Or do you think, "Why are my memory latency choices bad, worse and worst"? Or are you like me and try not to think about it at all? Well for all of the above, this option rocks. Executive summary: There is a option which attempts to improve the performance of an applicationon a NUMA machine by increasing the application's use of...

Monday, May 19, 2008 | General | Read More

Our Collectors

I drew this diagram on a white board for some customers recently. They seemed to like it (or were just being very polite) so I thought I redraw it for your amusement. Each blue box represents a collector that is used to collect a generation. The young generation is collected by the blue boxes in the yellow region and the tenured generation is collected by the blue boxes in the gray region. "Serial" is a stop-the-world, copying collector which uses a single GC thread. "ParNew"...

Friday, February 1, 2008 | Java | Read More

GC Errata 2

I know that none of you are still making the transition from jdk1.4.2 to jdk5 (aka jdk1.5.0, yah, we changed the numbering) but if you were, I'd want you to know that you might need a larger permanent generation. In jdk5 class data sharing was implemented (the -Xshare option, see the "java -X" output) when the client VM (-client) is being used. The implementation of class data sharing split some of the information about classes into two parts (the part thatcan be shared and...

Thursday, January 10, 2008 | Java | Read More

Did You Know ...

These are a few esoteric factoids that I never expected users to need, but which have actually come up recently. Most of the text is just background information. If you already recognize the command line flags that I've bold'ed, you probably already know more than is good for you. ParallelCMSThreads The low-pause collector (UseConcMarkSweepGC) does parts of the collection of the tenured generation concurrently with the execution of the application(i.e., not during a...

Friday, October 26, 2007 | Java | Read More

Size Matters

I recently had an interesting exchange with a customer about concurrent mode failures with the low-pause collector. My initial response was with my litany of whys and wherefores of concurrent mode failures. But it got more interesting, because it turned out to be an example of where object sizes and the young generation size made an unexpected difference. Before I get to that let's talk a little bit about the JVM's behavior with regard toallocating large objects. Large, of...

Friday, June 22, 2007 | Java | Read More

Get What You Need

As we all know by now GC ergonomics exists to automatically adjust the sizes of the generations to achieve a pause time goal and/or a throughput goal while using a minimum heap size. But sometimes that's not what you really want. I was talking to a user recently who was using java.lang.Runtime.totalMemory() and java.lang.Runtime.freeMemory() to monitor how full the heap was. The intent was that the user's application beable to anticipate when a GC was coming and to throttle...

Monday, April 23, 2007 | Java | Read More

GC Errata 1

Just some tid bits of information to fill some of the holes in the documentation. GC ergonomics is used by default on server class machines. Please see http://java.sun.com/docs/hotspot/gc5.0/ergo5.html for a description of GC ergonomics and server class machine. The flag "-server" causes the server VM to be used. "-server" does not cause the platform on which the VM is running to be considered a server class machine. Prior to JDK6 the UseParallelGC collector (with GC...

Monday, March 5, 2007 | Java | Read More

How Does Your Garden Grow?

Actually, the title should be "How Does Your Generation Grow" but then the literary reference would have been totally lost. I've written about how the generations grow if you are using GC ergonomics. http://blogs.sun.com/jonthecollector/entry/it_s_not_magic What if you're not using GC ergonomics? There is a different policy for growing and shrinking the heap that is used by the low pause collector and the serial collector. Ifyou're interested in that policy, this is you're...

Monday, February 12, 2007 | Java | Read More

JDK6 GC Release notes

Here's a couple of pointers to the GC section of the release notes for JDK6. "http://java.sun.com/javase/6/docs/technotes/guides/vm/par-compaction-6.html"> Parallel Compaction Concurrent Mark Sweep Collector Enhancements Edit done May 16, 2007. Ryan and Tobais, sorry but I just saw your comments. I could not figure out how to reply with a comment (comment period being closed and I didn't want to mess with the settings too much) so I'm editting the blog to respond. Ryan, The line...

Tuesday, February 6, 2007 | Java | Read More

When You're at Your Limit

It's often the case that we advise users of large applications to use large young generations. The rational is that large applications (very often multithreaded) have large allocation rates and a large young generations is good because it allows more time between minor collections. One case where that is not a good idea is when you're using the largest heap you can (e.g. close to 4G on a 32 bit system) and the live data is bigger than will fit in the tenured generation. When...

Thursday, January 11, 2007 | Java | Read More

Presenting the Permanent Generation

Have you ever wondered how the permanent generation fits into our generational system? Ever been curious about what's in the permanent generation. Are objects ever promoted into it? Ever promoted out? We'll you're not alone. Here are some of the answers. Java objects are instantiations of Java classes. Our JVM has an internal representation of those Java objects and those internal representations are stored in the heap (in the young generation or the tenured generation).Our...

Tuesday, November 28, 2006 | Java | Read More

Why Now?

Are you ever surprised by the occurrence of a full collection (aka major collection)? Generally a full collection only happens when an allocation is attempted and there is not enough space available in any of the generations. But there are exceptions to that rule and here are some of them. Actually, these are all of them that I could think of. I thought I would have a longer list so to fill out this blog I've includedsome bugs that relate to full collections that might...

Thursday, October 26, 2006 | Java | Read More

The Second Most Important GC Tuning Knob

is NewRatio or it's equivalent. Number 1 would be the total heap size. And just so the guys down the hall don't start throwing rocks at me, the 0-th most important GC tuning knob is the choice of the type of garbage collector itself. But let's talk about number 2. NewRatio is a flag that specifies the amount of the total heap that will be partitioned into the young generation. It's the tenured-generation-size / young-generation-size. A NewRatio value of 2 means that the...

Monday, September 11, 2006 | Java | Read More

More of a Good Thing

The throughput collector is getting more parallel. In our J2SE 6 release there is an option in the throughput collector to collect the tenured generation using multiple GC threads. Yes, the UseParallelGC collector wasn't all that we wanted it to be in terms of parallelism. Without this recent work only the young generation was being collected in parallel. The option to turn on the parallel collection of the tenured generation is -XX:+UseParallelOldGC.That's the punch line for...

Wednesday, August 30, 2006 | Java | Read More

The GC whitepaper

There's a very nice whitepaper on our GC at http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf It talks about basic concepts, some specifics about our GC, suggestions on tuning, and some of the latest improvements such as the parallel old collector. If you've looked at the GC tuning guides, some of it will look familiar, but it nicely pulls together information from several sources.

Thursday, August 24, 2006 | Java | Read More

The Real Thing

Here's a real treat dished up by Ross K. who hangs out 3 offices down the hall. A while back I wrote a blog about thread local allocation buffers (TLAB's). The short comings of my blog have probably been annoying Ross so much that he's written this one for us. If there are any discrepancies between my earlier blog and this one, believe this one. Thanks, Ross. A Thread Local Allocation Buffer (TLAB) is a region of Edenthat is used for allocation by a single thread. It...

Tuesday, August 15, 2006 | Java | Read More

Location, Location, Location

Allocating a bunch of objects together and then using them together seems to be a good thing for cache utilization. Not always true, of course, but, if you're willing to take that as a quasi-truth, then you might be interested in how garbage collections can stir up that good locality. I'm going to talk first about our serial garbage collector. It is a generational garbage collector with a copying young generation collector and a mark-sweep-compacttenured generation collector....

Monday, August 14, 2006 | Java | Read More

Top 10 GC Reasons

to upgrade to J2SE 5.0 10) We fixed some bugs. 9) Thread local allocation buffer dynamic tuning. (see "A Little Thread Privacy Please") 8) Promotion failure handling was implemented for the low pause collector. Promotion failure handling is the ability to start a minor collection and then backout of it if there is not enough space in the tenured generation to promote all the objects that need to be promoted. In 5.0 the "young generation guarantee" need not apply for the low pause...

Wednesday, May 3, 2006 | Java | Read More

What the Heck's a Concurrent Mode?

and why does it fail? If you use the low pause collector, have you ever seen a message that contained the phase "concurrent mode failure" such as this? 174.445: [GC 174.446: [ParNew: 66408K->66408K(66416K), 0.0000618 secs]174.446: [CMS (concurrent mode failure): 161928K->162118K(175104K), 4.0975124 secs] 228336K->162118K(241520K) This is from a 6.0 (still under development) JDK but the same type of message can come out of a 5.0 JDK. Recall that the low pause collector is a...

Thursday, April 13, 2006 | Java | Read More

The Fault with Defaults

During early work on the low pause collector some of the applications we used for benchmarking the collector had the characteristic that objects had very short lifetimes or relatively long lifetimes with not much in between. All our current collectors use a copying collection for the young generation. This copying collection will copy the younger objects back into the young generation and copy the older objects into the tenured generation. The expectation is that more of theyo...

Tuesday, April 4, 2006 | Java | Read More

When the Sum of the Parts

doesn't equal a big enough hole. Did I mention that the low pause collector maintains free lists for the space available in the tenured generation and that fragmentation can become a problem? If you're using the low pause collector and things are going just peachy for days and days and then there is a huge (relatively speaking) pause, the cause may be fragmentation in the tenured generation. In 1.4.2 and older releases in order to do a young generation collectionthere was a...

Monday, March 6, 2006 | Java | Read More

So What's It Worth to You?

Have you ever gone to your favorite restaurant, had a great meal and sat back with your second cup of coffee and asked "Why can't those guys do a pausless garbage collector? How hard can it be?" Well, you're not the only one. That question came up around here recently. There are techniques for doing pauseless garbage collection. The problem is that it costs in terms of application performance or additional Java heap size. Threads in an application read andwrite objects. The...

Wednesday, February 15, 2006 | Java | Read More

Tell Us Where It Hurts

Here's a URL for asking GC questions. http://java.sun.com/docs/forms/gc-sendusmail.html Engineers in the GC group answer the questions so that's probably as good as it gets. Updated 2008/2/20 The link above no longer takes you to the form for asking GC related questions. I'm leaving this information above just to save a little bit of confusion (i.e., you won't find yourself saying "Didn't this page used to ..."). The new channel for asking questions is explained below. Questions...

Wednesday, February 1, 2006 | Java | Read More

Why not a Grand Unified Garbage Collector?

At last count we have three garbage collectors. the parallel collector the low pause collector the serial collector Why is there more than one? Actually, the usual answer applies. Specialization often results in better performance. If you're interested in more particulars about our garbage collectors, read on. All three collectors are generational (young generation and tenured generation). Let's do the easy comparison first, why a parallel collector and a serialcollector....

Thursday, January 26, 2006 | Java | Read More

A Little Thread Privacy Please

This is not really about garbage collection but hopefully you'll find it interesting. And there is no punch line (i.e., cool command line flag that I can suggest to make your application run better). It's just a story about letting the VM do it. If you're using multiple threads (or one of the Java libraries is using multiple threads in your behalf) then threads in your application are doing allocationsconcurrently. All the threads are allocating from the same heap so some...

Friday, January 13, 2006 | Java | Read More

Since It's Not Magic

So by now you've tried GC ergonomics and things are working pretty well. If you didn't have any GC related command line flags, your reactions could run the gamut from the "big yawn" to an eye-popping "that's cool". The "big yawn" means that GC probably doesn't matter for your application. The "that's cool" means that GC matters but nobody ever told you. If you did have a bunch of GC related command line flags and you threw them outin order to try GC ergonomics, then 80% of...

Monday, January 2, 2006 | Java | Read More

When Are You Out of Memory?

You know why you get an out-of-memory exception, right? Your live data exceeds the space available in the Java heap. Well, that's very nearly, always right. Very, very nearly. If the Java heap is barely large enough to hold all the live data, the JVM could be doing almost continual garbage collections. For example if 98% of the data in the heap is live, then there is only 2% that is available for new objects. If the applicationis using that 2% for temporary objects, it can...

Wednesday, December 14, 2005 | Java | Read More

What Are We Thinking?

What's next for GC ergonomics? Just a friendly warning. This one verges on GC stream-of-consciousness ramblings. GC ergonomics has been implemented so far in the throughput collector only. We've been thinking about how to extend it to the low pause collector. The low pause collector currently is implemented as a collector that does some of it's work while the application continues to run. It's described in http://java.sun.com/docs/hotspot Some of the policies we used in the...

Tuesday, December 6, 2005 | Java | Read More

What Were We Thinking?

There were some decisions made during the development of GC ergonomics that perhaps deserve some explanation. For example, The pause time goal comes first. A pause is a pause is a pause. Ignore the cost of System.gc()'s. Why is the pause time goal satisfied first? GC ergonomics tries to satisfy a pause time goal before considering any throughput goal. Why not the throughput goal first? I tried both ways with a variety of applications.As one might expect it was not black and...

Monday, October 24, 2005 | Java | Read More

Where Are the Sharp Edges?

In general GC ergonomics works best for an application that has reached a steady state behavior in terms of its allocation pattern. Or at least it is not changing its allocation pattern quickly. GC ergonomics measures the pause times and throughput of the application and changes the size of the heap based on those measurements. The measurements of pause time and throughput are kept in terms of a weighted average where (as one would expect) the most recent measurements are...

Wednesday, October 5, 2005 | Java | Read More

It's Not Magic

In our J2SE (tm) 1.5.0 release we added a new way of tuning the Java(tm) heap which we call "garbage collector (GC) ergonomics". This was added only to the parallel GC collector. You may also have seen it referred to as "Smart Tuning" or "Simplified Tuning". GC ergonomics allows a user to tune the Java heap by specifying a desired behavior for the application. These behaviors are a maximum pause time goal and a throughput goal. So what is GC ergonomics? Prior J2SE 1.5.0 if you...

Monday, September 26, 2005 | Java | Read More