[go: up one dir, main page]

0% found this document useful (0 votes)
136 views13 pages

GC

1) Java heap memory is divided into generations (young, old, permanent) for garbage collection. 2) New objects are created in the young generation and may be promoted to the old generation. 3) Minor garbage collections move objects within the young generation while major collections promote to the old generation. 4) Major collections pause all application threads, potentially reducing performance.

Uploaded by

Ravi Bhardwaj
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
136 views13 pages

GC

1) Java heap memory is divided into generations (young, old, permanent) for garbage collection. 2) New objects are created in the young generation and may be promoted to the old generation. 3) Minor garbage collections move objects within the young generation while major collections promote to the old generation. 4) Major collections pause all application threads, potentially reducing performance.

Uploaded by

Ravi Bhardwaj
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODT, PDF, TXT or read online on Scribd
You are on page 1/ 13

How Garbage Collection works in Java 1) objects are created on heap in Java irrespective of there scope e.g.

local or member variable. while its worth noting that class variables or static members are created in method area of Java memory space and both heap and method area is shared between different thread. 2) Garbage collection is a mechanism provided by Java Virtual Machine to reclaim heap space from objects which are eligible for Garbage collection. 3) Garbage collection relieves java programmer from memory management which is essential part of C++ programming and gives more time to focus on business logic. 4) Garbage Collection in Java is carried by a daemon thread called Garbage Collector. 5) Before removing an object from memory Garbage collection thread invokes finalize () method of that object and gives an opportunity to perform any sort of cleanup required. 6) You as Java programmer can not force Garbage collection in Java; it will only trigger if JVM thinks it needs a garbage collection based on Java heap size. 7) There are methods like System.gc () and Runtime.gc () which is used to send request of Garbage collection to JVM but its not guaranteed that garbage collection will happen. 8) If there is no memory space for creating new object in Heap Java Virtual Machine throws OutOfMemoryError or java.lang.OutOfMemoryError heap space

When an Object becomes Eligible for Garbage Collection An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static references in other words you can say that an object becomes eligible for garbage collection if its all references are null. Cyclic dependencies are not counted as reference so if Object A has reference of object B and object B has reference of Object A and they don't have any other live reference then both Objects A and B will be eligible for Garbage collection. Generally an object becomes eligible for garbage collection in Java on following cases: 1) All references of that object explicitly set to null e.g. object = null 2) Object is created inside a block and reference goes out scope once control exit that block. 3) Parent object set to null, if an object holds reference of another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection. Heap Generations for Garbage Collection in Java Java objects are created in Heap and Heap is divided into three parts or generations for sake of garbage collection in Java, these are called as Young generation, Tenured or Old Generation and Perm Area of heap. New Generation is further divided into three parts known as Eden space, Survivor 1 and Survivor 2 space. When an object first created in heap its gets created in new generation inside Eden space and after subsequent Minor Garbage collection if object survives its gets moved to survivor 1 and then Survivor 2 before Major Garbage collection moved that object to Old or tenured generation. Permanent generation of Heap or Perm Area of Heap is somewhat special and it is used to store Meta data related to classes and method in JVM, it also hosts String pool provided by JVM as discussed in my string tutorial why String is immutable in Java. Types of Garbage Collector in Java Java Runtime (J2SE 5) provides various types of Garbage

collection in Java which you can choose based upon your application's performance requirement. Java 5 adds three additional garbage collectors except serial garbage collector. Each is generational garbage collector which has been implemented to increase throughput of the application or to reduce garbage collection pause times. 1) Throughput Garbage Collector: This garbage collector in Java uses a parallel version of the young generation collector. It is used if the -XX:+UseParallelGC option is passed to the JVM via command line options . The tenured generation collector is same as the serial collector. 2) Concurrent low pause Collector: This Collector is used if the -XX:+UseConcMarkSweepGC is passed on the command line. This is also referred as Concurrent Mark Sweep Garbage collector. The concurrent collector is used to collect the tenured generation and does most of the collection concurrently with the execution of the application. The application is paused for short periods during the collection. A parallel version of the young generation copying collector is sued with the concurrent collector. Concurrent Mark Sweep Garbage collector is most widely used garbage collector in java and it uses algorithm to first mark object which needs to collected when garbage collection triggers. 3) The Incremental (Sometimes called train) low pause collector: This collector is used only if -XX: +UseTrainGC is passed on the command line. This garbage collector has not changed since the java 1.4.2 and is currently not under active development. It will not be supported in future releases so avoid using this and please see 1.4.2 GC Tuning document for information on this collector. Important point to not is that -XX:+UseParallelGC should not be used with -XX: +UseConcMarkSweepGC. The argument passing in the J2SE platform starting with version 1.4.2 should only allow legal combination of command line options for garbage collector but earlier releases may not find or detect all illegal combination and the results for illegal combination are unpredictable. Its not recommended to use this garbage collector in java. JVM Parameters for garbage collection in Java Garbage collection tuning is a long exercise and requires lot of profiling of application and patience to get it right. Garbage collection tuning largely depends on application profile, what kind of object application has and what are there average lifetime etc. for example if an application has too many short lived object then making Eden space wide enough or larger will reduces number of minor collections. you can also control size of both young and Tenured generation using JVM parameters for example setting -XX:NewRatio=3 means that the ratio among the young and tenured generation is 1:3 , you got to be careful on sizing these generation. As making young generation larger will reduce size of tenured generation which will force Major collection to occur more frequently which pauses application thread during that duration results in degraded or reduced throughput. The parameters NewSize and MaxNewSize are used to specify the young generation size from below and above. Setting these equal to one another fixes the young generation. Full GC and Concurrent Garbage Collection in Java Concurrent garbage collector in java uses a single garbage collector thread that runs concurrently with the application threads with the goal of completing the collection of the tenured generation before it becomes full. In normal operation, the concurrent garbage collector is able to do most of its work with the application threads still running, so only brief pauses are seen by the application threads. As a fall back, if the concurrent garbage collector is unable to finish before the tenured generation fill up, the application is paused and the collection is completed with all the application threads stopped. Such

Collections with the application stopped are referred as full garbage collections or full GC and are a sign that some adjustments need to be made to the concurrent collection parameters. Always try to avoid or minimize full garbage collection or Full GC because it affects performance of Java application. When you work in finance domain for electronic trading platform and with high volume low latency systems performance of java application becomes extremely critical an you definitely like to avoid full GC during trading period. Summary on Garbage collection in Java 1) Java Heap is divided into three generation for sake of garbage collection. These are young generation, tenured or old generation and Perm area. 2) New objects are created into young generation and subsequently moved to old generation. 3) String pool is created in Perm area of Heap, garbage collection can occur in perm space but depends upon JVM to JVM. 4) Minor garbage collection is used to move object from Eden space to Survivor 1 and Survivor 2 space and Major collection is used to move object from young to tenured generation. 5) Whenever Major garbage collection occurs application threads stops during that period which will reduce applications performance and throughput. 6) There is no manual way of doing garbage collection in Java. Analyzing GC -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/NotBackedUp/jboss-eap5.1.2/jboss-as/server/allgc.log [GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs] -XX:+PrintGCDetails [GC [DefNew: 64575K->959K(64576K), 0.0457646 secs] 196016K->133633K(261184K), 0.0459067 secs]] indicates that the minor collection recovered about 98% of the young generation, DefNew: 64575K->959K(64576K) and took about 46 milliseconds. 0.0457646 secs The usage of the entire heap was reduced to about 51% 196016K->133633K(261184K) and that there was some slight additional overhead for the collection (over and above the collection of the young generation) as indicated by the final time: 0.0459067 secs

SurvivorRatio The parameter SurvivorRatio can be used to tune the size of the survivor spaces, but this is often not as important for performance. For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6. In other words, each survivor space will be one eighth 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. At each garbage collection the virtual machine chooses a threshold number of times an object can be copied before it is tenured. This threshold is chosen to keep the survivors half full. An option, -XX:+PrintTenuringDistribution, can be used to show this threshold and the ages of objects in the new generation. It is also useful for observing the lifetime distribution of an application. ** Introduction:

** Young Generation:

** Minor generation:

illustrates the operation of a minor collection (objects that have been found to be garbage are marked

with a gray X). Live objects in the Eden that survive the collection are copied to the unused survivor space. Live objects in the survivor space that is in use, which will be given another chance to die in the young generation, are also copied to the unused survivor space. Finally, live objects in the survivor space that is in use, which are deemed "old enough," are promoted to the old generation. At the end of the minor collection, the two survivor spaces swap roles . The Eden is entirely empty; only one survivor space is in use; and the occupancy of the old generation has grown slightly. Because live objects are copied during its operation, this type of collector is called a copying collector.

The Serial Collector The configuration of the Serial Collector is a young generation over an old generation managed by a sliding compacting mark-sweep, also known as a mark-compact, collector. Both minor and major collections take place in a stop-the-world fashion (i.e., the application is stopped while a collection is taking place). Only after the collection has finished is the application restarted The mark-compact collector first identifies which objects are still live in the old generation. It then slides them towards the beginning of the heap, leaving any free space in a single contiguous chunk at the end of the heap. This allows any future allocations into the old generation, which will most likely take place as objects are being promoted from the young generation, to use the fast bump-the-pointer technique.

The Serial Collector is the collector of choice for most applications that do not have low pause time requirements and run on client-style machines. It takes advantage of only a single CPU for garbage collection work. The Parallel Collector: Throughput Matters!

To decrease garbage cThese days, a lot of important Java applications run on (sometimes dedicated) servers with a lot of physical memory and multiple CPUs. Ideally, the garbage collector can take advantage of all available CPUs and not leave most of them idle while only one does garbage collection work. To decrease garbage collection overhead and hence increase application throughput, on server-style machines, the Java HotSpot VM includes the Parallel Collector, also called the Throughput Collector. Its operation is similar to that of the Serial Collector (i.e., it is a stop-the-world collector with the young generation over a mark-compact old generation). However, the minor collections take place in parallel, using all available CPUs The Mostly-Concurrent Collector: Latency Matters!

It starts with a short pause, called initial mark, that identifies the set of objects that are immediately reachable from outside the heap. Then, during the concurrent marking phase, it marks all live objects that are transitively reachable from this set. Because the application is running and updating reference fields (hence, modifying the object graph) while the marking phase is taking place, not all live objects are guaranteed to be marked at the end of the concurrent marking phase. To deal with this, the application stops again for a second pause, called remark, which finalizes marking by revisiting any objects that were modified during the concurrent marking phase. The card table data structure is reused to also keep track of modified objects. Because the remark pause is more substantial than the initial mark, it is "parallelized" to increase its efficiency. At the end of the remark phase, all live objects in the heap are guaranteed to have been marked. Since revisiting objects during the remark phase increases the amount of work the collector has to do, its overhead increases as well. This is a typical trade-off for most collectors that attempt to reduce pause times. Having identified all live objects in the old generation, the final phase of the collection cycle is the concurrent sweeping phase, which sweeps over the heap, de-allocating garbage objects in-place without relocating the live ones

HotSpot GC collectors
HotSpot JVM may use one of 6 combinations of garbage collection algorithms listed below. Young collector
Serial (DefNew) Parallel scavenge (PSYoungGen) Parallel scavenge (PSYoungGen) Serial (DefNew) Parallel (ParNew)

Old collector
Serial Mark-Sweep-Compact Serial Mark-Sweep-Compact (PSOldGen) Parallel Mark-Sweep-Compact (ParOldGen) Concurrent Mark Sweep Concurrent Mark Sweep

JVM option
-XX:+UseSerialGC -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:+UseConcMarkSweepGC -XX:-UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC

G1

-XX:+UseG1GC

GC logging options
JVM option General options
-verbose:gc

Description Print basic GC info Print more elaborated GC info Print timestamps for each GC event (seconds count from start of JVM) Redirects GC output to file instead of console Print detailed demography of young space after each collection Print TLAB allocation statistics Print pause summary after each stop-the-world pause Print time for each concurrent phase of GC Creates heap dump file after full GC Creates heap dump file before full GC Creates heap dump in out-of-memory condition Specifies path to save heap dumps

or -XX:+PrintGC

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:<file> -XX:+PrintTenuringDistribution -XX:+PrintTLAB -XX:+PrintGCApplication\ StoppedTime -XX:+PrintGCApplication\ ConcurrentTime -XX:+HeapDumpAfterFullGC -XX:+HeapDumpBeforeFullGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path>

CMS specific options


-XX:PrintCMSStatistics=<n> -XX:+PrintCMSInitiationStatistics -XX:PrintFLSStatistics=2 -XX:PrintFLSCensus=2 -XX:+CMSDumpAtPromotionFailure

Print additional CMS statistics if n >= 1 Print CMS initiation details Print additional info concerning free lists Print additional info concerning free lists Dump useful information about the state of the CMS old generation upon a promotion failure. In a CMS dump enabled by option above, include more detailed information about the free chunks. In a CMS dump enabled by option above, include more detailed information about the allocated objects.

-XX:+CMSPrintChunksInDump

-XX:+CMSPrintObjectsInDump

JVM sizing options


JVM option
-Xms<size> -Xmx<size>

Description Initial and max size of heap space (young space + tenured space). Permanent space does not count to this size. Initial and max size of young space. Alternative way to specify young space size. Sets ration of young vs tenured space (e.g. -XX:NewRatio=2 means that young space will be 2 time smaller than tenuted space). Sets size of single survivor space as a portion of Eden space size (e.g. -XX:NewSize=64m -XX:SurvivorRatio=6 means that each survivor space will be 8m and eden will be 48m). Initial and max size of permanent space. Sets size of stack area dedicated to each thread. Thread stacks do not count to heap size. Maximum size of off-heap memory available for JVM

or -XX:InitialHeapSize=<size>
-XX:MaxHeapSize=<size> -XX:NewSize=<size> -XX:MaxNewSize=<size>

-XX:NewRatio=<ratio>

-XX:SurvivorRatio=<ratio>

-XX:PermSize=<size> -XX:MaxPermSize=<size> -Xss=<size> or -XX:ThreadStackSize=<size> -XX:MaxDirectMemorySize=<value>

Young collection tuning


JVM option
-XX:InitialTenuringThreshold=<n> -XX:MaxTenuringThreshold=<n>

Description Initial value for tenuring threshold (number of collections before object will be promoted to tenured space). Max value for tenuring threshold. Max object size allowed to be allocated in young space (large objects will be allocated directly in old space). Thread local allocation bypasses this check so if TLAB is large enough object exciding size threshold still may be allocated in young. Promote all objects surviving young collection immediately to tenured space (equivalent of -XX:MaxTenuringThreshold=0) Objects from young space will never get promoted to tenured space while survivor space is large enough to keep them. Use thread local allocation blocks in young space. Enabled by default. Allow JVM to adaptively resize TLAB for threads. Initial size of TLAB for thread Minimal allowed size of TLAB

-XX:PretenureSizeThreshold=<size>

-XX:+AlwaysTenure

-XX:+NeverTenure

Thread local allocation blocks


-XX:+UseTLAB -XX:+ResizeTLAB -XX:TLABSize=<size> -XX:MinTLABSize=<size>

CMS tuning options


JVM option Controlling initial mark phase
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiating\ OccupancyFraction=<n>

Description Only use occupancy as a criterion for starting a CMS collection. Percentage CMS generation occupancy to start a CMS collection cycle. A negative value means that CMSTriggerRatio is used. Percentage CMS generation occupancy at which to initiate CMS collection for bootstrapping collection stats.

-XX:CMSBootstrapOccupancy=<n>

-XX:CMSTriggerRatio=<n>

Percentage of MinHeapFreeRatio in CMS generation that is allocated before a CMS collection cycle commences. Percentage of MinHeapFreeRatio in the CMS perm generation that is allocated before a CMS collection cycle commences, that also collects the perm generation. Once CMS collection is triggered, it will wait for next young collection to perform initial mark right after. This parameter specifies how long CMS can wait for young collection. Force young collection before remark phase. If Eden used is below this value, don't try to schedule remark The Eden occupancy % at which to try and schedule remark pause Start sampling Eden top at least before young generation occupancy reaches 1/n of the size at which we plan to schedule remark Use parallel algorithm for young space collection. Use multiple threads for concurrent phases. Number of parallel threads used for concurrent phase. Number of parallel threads used for stopthe-world phases. Enable incremental CMS mode. Incremental mode is meant for severs with small number of CPU. If not enabled, CMS will not clean permanent space. You should always enable it in multiple class loader environments such as JEE or OSGi. Let System.gc() trigger concurrent collection instead of full GC.

-XX:CMSTriggerPermRatio=<n>

-XX:CMSWaitDuration=<timeout>

Controlling remark phase


-XX:+CMSScavengeBeforeRemark -XX:+CMSScheduleRemark\ EdenSizeThreshold -XX:CMSScheduleRemark\ EdenPenetration=<n> -XX:CMSScheduleRemark\ SamplingRatio=<n>

Parallel execution
-XX:+UseParNewGC -XX:+CMSConcurrentMTEnabled -XX:ConcGCThreads=<n> -XX:+ParallelGCThreads=<n>

CMS incremental mode


-XX:+CMSIncrementalMode

Miscellaneous options
-XX:+CMSClassUnloadingEnabled

-XX:+ExplicitGCInvokesConcurrent

-XX:+ExplicitGCInvokesConcurrent\
AndUnloadsClasses

Same as above but also triggers permanent space collection.

Miscellaneous GC options
JVM option
-XX:+DisableExplicitGC

Description JVM will ignore application calls to System.gc()

For TLAB : https://blogs.oracle.com/jonthecollector/entry/the_real_thing

You might also like