jackyfkc.github.io

教土豆学计算机

Garbage Collection

针对于 Hotspot JVM

The JVM knows exactly what objects and arrays it has allocated.

Generations

Hotspot Heap Structure 来源 Java Garbage Collection Basics

Why Generational Garbage Collection?

Object Lifetime 来源 Java Garbage Collection Basics

The heap is divided into two generations, young and old. The young generation comprises three spaces, Eden and two survivor spaces, whereas the old generation has just one memory space.

Young Generation

Young Generation 来源: Sun Microsystems: Memory Management in the Java HotSpot™ Virtual Machine. 2006

The Young generation is meant to hold short-lived objects while the Old generation is intended for objects with longer lifetimes.

Objects are created in Eden by application threads, and are removed by a non-deterministic garbage collection cycle. The GC cycle runs when necessary (i.e., when available memory is getting low).

A simplified description of the garbage collection procedure: When Eden is full, a minor GC is run on Eden and objects that are alive from Eden and Survivor1 are copied to Survivor2. The Survivor regions are swapped.

If an object is old enough or Survivor2 is full, it is moved to Old. Finally when Old is close to full, a full GC is invoked.

Serial young generation collection 来源: Sun Microsystems: Memory Management in the Java HotSpot™ Virtual Machine. 2006

After a young generation collection

After a young generation collection 来源: Sun Microsystems: Memory Management in the Java HotSpot™ Virtual Machine. 2006

Changed On Java8

Java 8 Memory Management

Heap sizes

Initial and Maximum Heap Sizes

The maximum heap size is not actually used by the JVM unless the program creates enough objects to require it. A much smaller amount, called the initial heap size, is allocated during JVM initialization.

To verify the default values, use the -XX:+PrintFlagsFinal option and look for MaxHeapSize in the output. For example, on Linux or Solaris, we can run the following: java -XX:+PrintFlagsFinal <GC options> -version | grep MaxHeapSize

Common Heap settings

Guidelines

The following are general guidelines regarding heap sizes for server applications:

Garbage Collectors

Java Collectors 来源 https://blogs.oracle.com/jonthecollector/our-collectors

The Serial GC

The serial collector is the default for client style machines in Java SE 5 and 6. With the serial collector, both minor and major garbage collections are done serially (using a single virtual CPU).

In addition, it uses a mark-compact collection method. This method moves older memory to the beginning of the heap so that new memory allocations are made into a single continuous chunk of memory at the end of the heap. This compacting of memory makes it faster to allocate new chunks of memory to the heap.

When to Use

The Serial GC is the garbage 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 virtual processor for garbage collection work (therefore, its name)

To enable the Serial Collector use: -XX:+UseSerialGC

The Parallel GC

The parallel garbage collector uses multiple threads to perform the young generation garbage collection.

By default on a host with N CPUs, the parallel garbage collector uses N garbage collector threads in the collection. The number of garbage collector threads can be controlled with command-line options: -XX:ParallelGCThreads=<desired number>

-XX:+UseParallelGC

With this command line option we get a multi-thread young generation collector with a single-threaded old generation collector. The option also does single-threaded compaction of old generation.

-XX:+UseParallelOldGC

With the -XX:+UseParallelOldGC option, the GC is both a multi-threaded young generation collector and multi-threaded old generation collector. It is also a multi-threaded compacting collector.

HotSpot does compaction only in the old generation. Young generation in HotSpot is considered a copy collector; therefore, there is no need for compaction.

When to use

The Parallel collector is also called a throughput collector. Since it can use multiple CPUs to speed up application throughput. This collector should be used when a lot of work need to be done and long pauses are acceptable. For example, batch processing like printing reports or bills or performing a large number of database queries.

Concurrent Mark Sweep (CMS) Collector

The Concurrent Mark Sweep (CMS) collector (also referred to as the concurrent low pause collector) collects the tenured generation. It attempts to minimize the pauses due to garbage collection by doing most of the garbage collection work concurrently with the application threads.

Normally the concurrent low pause collector does not copy or compact the live objects. A garbage collection is done without moving the live objects. If fragmentation becomes a problem, allocate a larger heap.

The CMS collector attempts to reduce pause times due to major collections by using separate garbage collector threads to trace the reachable objects concurrently with the execution of the application threads.

During each major collection cycle, the CMS collector pauses all the application threads for a brief period at the beginning of the collection and again toward the middle of the collection.

The second pause tends to be the longer of the two pauses. Multiple threads are used to do the collection work during both pauses.

The remainder of the collection (including most of the tracing of live objects and sweeping of unreachable objects is done with one or more garbage collector threads that run concurrently with the application. Minor collections can interleave with an ongoing major cycle, and are done in a manner similar to the parallel collector (in particular, the application threads are stopped during minor collections).

When to use

The CMS collector should be used for applications that require low pause times and can share resources with the garbage collector. Examples include desktop UI application that respond to events, a web server responding to a request or a database responding to queries.

To enable the CMS Collector use: -XX:+UseConcMarkSweepGC and to set the number of threads use: -XX:ParallelCMSThreads=<n>

The G1 Garbage Collection

The Garbage First or G1 garbage collector is available in Java 7 and is designed to be the long term replacement for the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector that has quite a different layout from the other garbage collectors.

To enable the G1 Collector use: -XX:+UseG1GC

Garbage Collection Tuning

Priority of Goals

The goals are addressed in the following order:

Measuring the Impact of GC

The first step in GC tuning is to collect statistics on how frequently garbage collection occurs and the amount of time spent GC. This can be done by adding -verbose:gc -XX:+PrintGCDetails, -XX:+PrintGCTimeStamps to the Java options.

Advanced GC Tuning

The goal of GC tuning is to ensure that only long-lived objects are stored in the Old generation and that the Young generation is sufficiently sized to store short-lived objects.

Some steps which may be useful are:

Someone’s experience suggests that the effect of GC tuning depends on your application and the amount of memory available. There are many more tuning options described online, but at a high level, managing how frequently full GC takes place can help in reducing the overhead.

Further Readings

Online Articles


Books