I need to use jstat to measure some GC parameters of a program. Jstat provides set of parameters ( S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT)
From those I am bit confused with the descriptions for YGCT, FGCT and GCT.
(YGCT Young generation garbage collection time.
FGCT Full garbage collection time.
GCT Total garbage collection time.)
I have 2 questions.
1) What does these three parameters (YGCT, FGCT and GCT) actually measure? A small comparison would be very helpful
2) I how can I know the unit of time that they are mentioning? (milliseconds/ seconds/.... )
I referred many documentations including
Interpreting jstat results
http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/
http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstat.html#output_options
But these does not answer my real question.
Could anyone how has experienced with jstat help me with this?
Thank you.
YGCT - Seconds spent in young generation collections since the JVM
started
FGCT - Seconds spent doing full garbage collections since the
JVM started
GCT - the sum of the above two values
This knowledge comes from experience and testing - I have not found a good reference defining the time unit and exact meaning.
S0C – Current survivor space 0 capacity (KB).
S1C – Current survivor space 1 capacity (KB).
S0U – Survivor space 0 utilization (KB).
S1U – Survivor space 1 utilization (KB).
EC – Current eden space capacity (KB).
EU – Eden space utilization (KB).
OC – Current old space capacity (KB).
OU – Old space utilization (KB).
PC – Current permanent space capacity (KB).
PU – Permanent space utilization (KB).
YGC – Number of young generation GC Events.
YGCT – Young generation garbage collection time.
FGC – Number of full GC events.
FGCT – Full garbage collection time.
GCT – Total garbage collection time.
FGCT +YGCT = GCT
FGCT /FGC = avg time taken per full gc cycle
YGCT / YGC = avg time taken per each young GC
these are useful whenyou are dealing with GC stats.
Related
jmap can know size of each generation, but I want to monitor my java process real time.
With jmx, MemoryMXBean.getHeapMemoryUsage().getUsed() can get the total heap size. But I cannot find any method to get:
Size of New (Young) and Tenured (Old) generations;
Size of Eden and each Survivor in New generations.
You can use ManagementFactory.getMemoryPoolMXBeans(). It shows all the memory regions. Depending on the GC you used, the names differ. pool.getCollectionUsage().getInit() gives the initial size of a pool. pool.getName() is for example 'G1 Eden Space' or 'G1 Old Gen' or 'G1 Survivor Space' if you use G1 GC.
pool.getUsage().getUsed() returns as well the amount of used memory for that region.
As we all know that in HotSpot there are seven GCs like Serial,CMS,G1 and so on.What I am confused is that all of them or only part of them is working at a time? How do them cooperate with each other to cover the task of garbage collection?
I appreciate any answer to this question.
Best wishes to everyone of you!
Below are possible combinations of GC algos in Java 8.
-XX:+UseSerialGC - Serail Young (DefNew) + Serial Old Mark Sweep Compact
-XX:+UseParallelGC - Parallel Young (PSYoungGen) + Serial Old Mark Sweep Compact
-XX:+UseParallelOldGC - Parallel Young (PSYoungGen) + Parallel Old Mark Sweep Compact
-XX:+UseParNewGC - Parallel Young (ParNew) + Serial Old Mark Sweep Compact
-XX:-UseParNewGC -XX:+UseConcMarkSweepGC - Serial Young (DefNew) + Concurrent Mark Sweep (Old)
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC - Parallel Young (ParNew) + Concurrent Mark Sweep (Old)
-XX:+UseG1GC - G1
Source of information.
Parallel Scavenge and ParNew are very similar, but ParNew is compatible with CMS (concurrent mark sweep) and Parallel Scavenge with parallel Mark Sweep Compact old space collectors.
G1 solely covers both young and old collections.
I am using JDK1.6.0_16 JVM for the java application that is hosted on an Linux Intel procesor 80 cores machine.
while starting the Java application I have only two options configured
-Xms2048m -Xmx8000m in the JVM Options (after java command).
I see that PS Old Gen is calculated as 5.21G and PS Eden is calcuated 2.6G but the PS Survivor space is 25MB.
I have exactly same JVM in production and in that PS Survivor Space size is shown as 888MB. I am seeing these sizes in java mission control Memory tab.
The cache size (output of /proc/cpuinfo) is showing 24656 in both UAT and production boxes.
Dont think it will make any difference for JVM but still mentioning that the there was very low load on machine at the time of starting JVM.
Can you please advise what parameters does JVM consider for calculating the PS Survivor Space size?
From oracle gc tuning article 1 and article 2 :
Survivor Space Sizing
You can use the parameter SurvivorRatio can be used to tune the size of the survivor spaces, but this is often not important for performance. For example, -XX:SurvivorRatio=6 sets the ratio between eden and a survivor space to 1:6.
In other words, each survivor space will be one-sixth the size of eden, and thus one-eighth the size of the young generation (not one-seventh, because there are two survivor spaces).
If survivor spaces are too small, copying collection overflows directly into the tenured generation. If survivor spaces are too large, they will be uselessly empty.
The NewSize and MaxNewSize parameters control the new generation’s minimum and maximum size. Regulate the new generation size by setting these parameters equal. The bigger the younger generation, the less often minor collections occur.
NewRatio: The size of the young generation relative to the old generation is controlled by NewRatio. For example, setting -XX:NewRatio=3 means that the ratio between the old and young generation is 1:3, the combined size of eden and the survivor spaces will be fourth of the heap.
As correctly quoted by Peter Lawrey, setting survivor depends on type of your application. From gc tuning article by Oracle, here are the guidelines.
First decide the maximum heap size you can afford to give the virtual machine. Then plot your performance metric against young generation sizes to find the best setting
If the total heap size is fixed, then increasing the young generation size requires reducing the tenured generation size. Keep the tenured generation large enough to hold all the live data used by the application at any given time, plus some amount of slack space (10 to 20% or more).
Subject to the previously stated constraint on the tenured generation: Grant plenty of memory to the young generation and increase the young generation size as you increase the number of processors, because allocation can be parallelized. The default is calculated from NewRatio and the -Xmx setting
Can you please advise what parameters does JVM consider for calculating the PS Survivor Space size?
It must large enough to never actually fill up after a collection of the Eden space, otherwise you will get Full GCs which is undesirable.
What is an optimal Survivor space size depends on your application. I suggest you test you application under realistic loads with a larger Eden and Survivor space than you imagine useful and see how much of that space ever gets used and add 50% to 100% based on what you see is used.
The machine has 256G of physical memory out of which ~200G
The default heap size is 32 GB and I suggest you use this default unless you have a good reason to reduce it.
-XX:SurvivorRatio=1
This is usually a bad idea and having a high survivor ratio like 8 is usually better.
Setting the value to 8 didnt have any effect
Most likely you have a low allocation rate. I usually set a high Young space, alike -Xmn8g or even -Xmn24g but whether this is a good/bad idea depends on your application.
I see the the PS survivor space is almost full (98 %) most of the time for my application. I don't know what is PS survivor space . Is this normal ?
What should be done in such scenarios ?
First, see e.g. here : What is a survivor space?
Usually, there are 2 survivor spaces in the YoungGeneration part of the heap (e.g. for the Hostpot VM ). They are there to allow objects to mature before promoting them to the Old Generation. Because its more expensive to cleanup the old generation.
Collect some statistics to see if the survivor spaces are really full most of the time. You should see that one is always empty while the other one is being populated. See e.g. this question for collecting GC stats.
Once you have the data, look for:
survivor space overflow - this occurs when the survivor space is too small to allow the objects to mature between YoungHeap collections and the objects are overflowing to the OldGeneration without having time to mature (and die before being promoted).
also, monitor tenuring distribution with -XX:+PrintTenuringDistribution. To see how fast are the objects maturing.
UPDATE: Read the Hotspot Memory Management Whitepaper and see the section Serial Collector, there is a nice explanations of the Survivor spaces:
Note: If the To space becomes full, the live objects from Eden or From that have not been
copied to it are tenured, regardless of how many young generation collections they have survived. Any
objects remaining in Eden or the From space after live objects have been copied are, by definition, not live, and they do not need to be examined.
Please feel free to correct me if I am wrong. In JVM heap, there are two generations, old and young. When doing full GC, in old generation, there are heavy operations like compact spaces and fixing the hole, which will make JVM hang. And I find in young generation, a light weighted GC is applied, and there are another area called Eden involved in young generation from my search results. However, after search a lot of documents, I still have two confusions about GC in young generation,
In young generation, it seems GC does not work in the way which old generation GC works (i.e. old generation GC compact and fixing the hole)? If so, how did GC in young generation works?
What is Eden space and how this space is utilized in young generation? Appreciate if any document for a newbie could be recommended.
This is the single, most important diagram you have to memorize and understand:
(source: oracle.com)
It comes from Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning, one stop place to learn everything about GC internals. But to address your immediate questions:
Allocating new objects using new operator (almost) always happens in Eden space. But Eden is actually a stack. When you create new object needing N bytes, single pointer advances by N bytes on that stack and that's it. Allocating is that fast, no searching for free spot, compacting, whatever.
Of course this stack is not infinite, at some point we'll reach its end, triggering minor GC. Also most likely multiple objects are already garbage. So what JVM does in minor GC is the following:
traverse graph of objects starting from GC roots
copy all objects reachable from GC roots to one of survivor spaces (no gaps, we know all of them and this is a single process)
wipe out eden space (basically just moving this stack pointer back to 0)
In subsequent minor collections there are additional steps:
one of survivor spaces is examined as well. Live objects from both eden and one of survivor spaces are copied to second survivor space. This means there is always exactly one free survivor space.
So how are objects ending in tenured generation? First young objects are copied to one of survivor spaces. Then they are copied to the other and again and again. Once given object jumps back and forth too many times (configurable, 8 by default), it is promoted to tenured space.
Major GC runs when tenured space is full.