• CozWeAreFriends Banner. Nice isn't it?
  • CozWeAreFriends Banner. Nice isn't it?
  • JVM Monitoring & Tunings – Tutorial 1 for Basic Knowledge

    Posted on April 22nd, 2012 by fath

    Hi All,

    Lately, I’ve been doing quite a lot of experimenting, tunings on JVM since this was one of the tasks given to me in my project. I’d like to share some of my notes to you guys. They might not be so detail, but I hope this would help those who are new in this topic. Cheers! 🙂

     

    INTRODUCTION

    serial collector – a single threaded collector
    parallel collector – multiple thread to collect garbage

    HOW IT WORKS

    the following collectors operate on the young generation:
    -XX:+UseSerialGC
    -XX:+UseParallelGC
    -XX:+UseParNewGC

    the following collectors operate on the old generation:
    -XX:+UseParallelOldGC
    -XX:+UseConcMarkSweepGC

    Both the serial and parallel collectors cause a stop-the-world during the GC.

    There are two differences between a parallel and a CMS collectors:

    1) the parallel uses multiple GC threads, while the CMS uses only one.
    2) the parallel is a ‘stop-the-world’ collector, while the CMS stops the world only during the initial mark and remark phases.
    during the concurrent marking and sweeping phases, the CMS thread runs along with the application’s threads.

    the CMS performs the following steps (all made by only one GC thread):
    – initial mark
    – concurrent marking
    – remark
    – concurrent sweeping

    Parallel & Conc can be combined in GC by using:
    – -XX:UserParNewGC for the new generation (multiple GC threads)
    – -XX:+UseConcMarkSweepGC for the old generation (one GC thread, freezes the JVM only during the initial mark and remark phases)

    WHEN TO USE FLAGS

    – In theory, the CMS should be used when you you want to reduce the time you application spends on GC freezes (Stop-The-World) by making the GC working concurrently with your application.
    – you’ll use parallel when you want to reduce the application freezes but not in the cost of interfering with your application threads.

    GC ALGORITHM

    Parallel (For Throughput Applications)
    |— -XX:+UseParallelOldGC – parallel garbage collector on young and old gen
    |— -XX:+UseParallelGC – parallel garbage collector on young and serial on old gen
    |— -XX:ParallelGCThreads=# – To modify the number of threads, use the flag , where # is the number of threads

    Concurrent (For Latency Applications)
    – can cause fragmentation on heap because the heap is not compacted on every single collection. It compacts when the new object cant fit in the heap.
    – the goal of concurrent is to reduce the number of full collections

    -XX:+UseConcMarkSweepGC
    |— -XX:+CMSIncrementalMode (perform different collection phases incrementally)
    |— -XX:CMSIncrementalSafetyFactor=# (# a number of 0-100; default=10%; larger value means giving more time for minor collection, if not helping, increase min duty cycle)
    |— -XX:CMSIncrementalDutyCycleMin=# (# a number of 0-100; The higher the number, the more minimum time you are willing to give to a minor collection.)

    SOME OTHER FLAGS OPTION

    By adding the flag -Xmn you can set the nursery size, and the remaining heap is then allocated to the tenured space.
    This tuning of the nursery can be an important source of performance improvements because a nursery collection is significantly faster than a full collection. This parameter allocates space in heap for the young generation. If you have available memory, you can increase the –Xmn value to increase young generation size. This reduces the frequency of minor collections and gives short-lived objects in the young generation more time to die.

    Using the flag -verbose:gc shows each nursery, full GC, how much was collected, and how much of the heap is free.
    Adding -XX:+PrintGCDetails increases the level of detail.

    SurvivorRatio?The SurvivorRatio parameter controls the size of the two survivor spaces in the young generation. For example: -XX:SurvivorRatio=8 sets the ratio between each survivor space and eden to be 1:8.

    TargetSurvivorRatio?The default value of TargetSurvivorRatio is 50. Increasing this (for example, by setting -XX:TargetSurvivorRatio=90) will allow better utilization of survivor space memory.

    The NewRatio argument defines the ratio of the tenured generation to the young generation. The default value is 2, which means the tenured generation occupies 2/3 of the memory and the young generation occupies 1/3. By profiling your application you can tune this value to improve performance. For example, if the profile of the application shows the young generation occupancy as 20%, you can define –XX:NewRatio=4, so that the tenured generation occupies 4/5 of the memory and the young generation occupies 1/5.

    HOW TO READ GC LOG

    Minor Collection
    [GC [DefNew: 910K->12K(960K), 0.0003947 secs] 1239K->341K(5056K), 0.0005048 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    [GC [DefNew: 908K->13K(960K), 0.0004003 secs] 1237K->341K(5056K), 0.0005126 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    [GC [DefNew: 909K->14K(960K), 0.0005241 secs] 1237K->342K(5056K), 0.0006367 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    Full Collection
    [Full GC [Tenured: 3485K->4095K(4096K), 0.1745373 secs] 61244K->7418K(63104K), [Perm : 10756K->10756K(12288K)], 0.1762129 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]

    What does all of that mean?  The first three lines are young generation or minor collections.  These are usually quick, and happen quite frequently.  The various parts of the young generation include  Nursery, From space, and To space.  Allocations happen in the nursery, so applications that allocate heavily need a large nursery to improve performance.  In this case, the nursery is 960k and has around 909k worth of data before the collection and around 13k after the collection.  The total size of the young generation (Nursery + From Space + To Space) is 5056k; it has around 1237k worth of data before the collection and about 341k after the collection.  The last line shows a full collection.  The tenured space is 4096k and — in this case — objects were moved into tenured space but none were collected.  Here you might have a different problem, in which the tenured space is too small and should be increased to help give better performance.

     

    Extra Notes:
    – increase xmn (young space) would reduce the number of minor collection, throughput increase.
    – Decreasing the survivor ratio will increase the size of survivor spaces. Larger survivor spaces allow short-lived objects a longer time period to die in the young generation
    – Note: Do not use -XX:+UseParallelGC with -XX:+UseConcMarkSweepGC.
    –XX:NewRatio= OLD/(young+survivor+survivor2)

     



    How to trace Garbage Collection

    Posted on March 15th, 2012 by fath

    How to trace Garbage Collection

    The two primary measures of garbage collection performance are throughput and pauses. Throughput is the percentage of the total time spent on other activities apart from GC. Pauses are times when an application appears unresponsive due to GC.

    Two other considerations are footprint and promptness. Footprint is the working size of the JVM process, measured in pages and cache lines. Promptness is the time between when an object becomes dead, and when the memory becomes available. This is an important consideration for distributed systems.

    JVM diagnostic output will display information on pauses due to GC. If you start the server in verbose mode (use the command asadmin start-domain –verbose domain), then the command line argument “-verbose:gc” prints information for every collection. Here is an example of output of the information generated with this JVM flag:

    [GC 50650K->21808K(76868K), 0.0478645 secs]
    [GC 51197K->22305K(76868K), 0.0478645 secs]
    [GC 52293K->23867K(76868K), 0.0478645 secs]
    [Full GC 52970K->1690K(76868K), 0.54789968 secs]

    On each line, the first number is the combined size of live objects before GC, the second number is the size of live objects after GC, the number in parenthesis is the total available space, which is the total heap minus one of the survivor spaces. The final figure is the amount of time that the GC took. This example shows three minor collections and one major collection. In the first GC, 50650 KB of objects existed before collection and 21808 KB of objects after collection. This means that 28842 KB of objects were dead and collected. The total heap size is 76868 KB. The collection process required 0.0478645 seconds.

    Other useful monitoring options:

    • -XX:+PrintGCDetails –  more detailed logging information
    • -Xloggc:file to save the details in a log file