Young Generation Collection Using the Serial Collector
Figure 3
illustrates the operation of a young generation collection using the serial
collector. The live
objects in Eden are copied to the initially empty
survivor space, labeled To in the figure, except for ones
that are too large
to fit comfortably in the To space. Such objects are directly copied to the
old
generation. The live objects in the occupied survivor space (labeled
From) that are still relatively young
are also copied to the other survivor
space, while objects that are relatively old are copied to the
old
generation. 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. (These garbage
objects are marked with an X in the figure,
though in fact the collector does
not examine or mark these objects.)
Figure 3. Serial young generation
collection
After a young generation collection is complete, both Eden and the
formerly occupied survivor space are
empty and only the formerly empty
survivor space contains live objects. At this point, the survivor
spaces swap
roles. See Figure 4.
8 Garbage Collectors in the J2SE 5.0 HotSpot JVM Sun
Microsystems, Inc.
Young Generation
Old Generation
Eden
From
To
empty Survivor Spaces
Figure 4. After a young generation
collection
Old Generation Collection Using the Serial Collector
With the
serial collector, the old and permanent generations are collected via a
mark-sweep-compact
collection algorithm. In the mark phase, the collector
identifies which objects are still live. The sweep
phase “sweeps” over the
generations, identifying garbage. The collector then performs
sliding
compaction, sliding the live objects towards the beginning of the old
generation space (and similarly for
the permanent generation), leaving any
free space in a single contiguous chunk at the opposite end. See
Figure 5.
The compaction allows any future allocations into the old or permanent
generation to use the
fast, bump-the-pointer technique.
Figure 5.
Compaction of the old generation
When to Use the Serial Collector
The
serial collector is the collector of choice for most applications that are run
on client-style machines
and that do not have a requirement for low pause
times. On today’s hardware, the serial collector can
efficiently manage a lot
of nontrivial applications with 64MB heaps and relatively short
worst-case
pauses of less than half a second for full collections.
Serial
Collector Selection
In the J2SE 5.0 release, the serial collector is
automatically chosen as the default garbage collector on
machines that are
not server-class machines, as described in Section 5. On other machines, the
serial
collector can be explicitly requested by using the -XX:+UseSerialGC
command line option.
Parallel Collector
These days, many Java applications
run on machines with a lot of physical memory and multiple CPUs. The
parallel
collector, also known as the throughput collector, was developed in order to
take advantage of available
CPUs rather than leaving most of them idle while
only one does garbage collection work.
Young Generation Collection Using the
Parallel Collector
The parallel collector uses a parallel version of the
young generation collection algorithm utilized by the
serial collector. It is
still a stop-the-world and copying collector, but performing the young
generation
9 Garbage Collectors in the J2SE 5.0 HotSpot JVM Sun Microsystems,
Inc.
a) Start of Compaction
b) End of Compaction
Young
Generation
Old Generation
Eden
To From
empty
empty
Survivor
Spaces
collection in parallel, using many CPUs, decreases garbage collection
overhead and hence increases
application throughput. Figure 6 illustrates the
differences between the serial collector and the parallel
collector for the
young generation.
Figure 6. Comparison between serial and parallel young
generation collection
Old Generation Collection Using the Parallel
Collector
Old generation garbage collection for the parallel collector is
done using the same serial mark-sweepcompact
collection algorithm as the
serial collector.
When to Use the Parallel Collector
Applications that can
benefit from the parallel collector are those that run on machines with more
than
one CPU and do not have pause time constraints, since infrequent, but
potentially long, old generation
collections will still occur. Examples of
applications for which the parallel collector is often appropriate
include
those that do batch processing, billing, payroll, scientific computing, and so
on.
You may want to consider choosing the parallel compacting collector
(described next) over the parallel
collector, since the former performs
parallel collections of all generations, not just the
young
generation.
Parallel Collector Selection
In the J2SE 5.0 release,
the parallel collector is automatically chosen as the default garbage collector
on
server-class machines (defined in Section 5). On other machines, the
parallel collector can be explicitly
requested by using the
-XX:+UseParallelGC command line option.
Parallel Compacting Collector
The
parallel compacting collector was introduced in J2SE 5.0 update 6. The
difference between it and the parallel
collector is that it uses a new
algorithm for old generation garbage collection. Note: Eventually, the
parallel
compacting collector will replace the parallel collector.
Young
Generation Collection Using the Parallel Compacting Collector
Young
generation garbage collection for the parallel compacting collector is done
using the same
algorithm as that for young generation collection using the
parallel collector.
Old Generation Collection Using the Parallel Compacting
Collector
With the parallel compacting collector, the old and permanent
generations are collected in a stop-theworld,
mostly parallel fashion with
sliding compaction. The collector utilizes three phases. First,
each
generation is logically divided into fixed-sized regions. In the marking
phase, the initial set of live objects
directly reachable from the
application code is divided among garbage collection threads, and then
all
live objects are marked in parallel. As an object is identified as live,
the data for the region it is in is
updated with information about the size
and location of the object.
10 Garbage Collectors in the J2SE 5.0 HotSpot JVM
Sun Microsystems, Inc.
Stop-the-world pause
Serial Collector Parallel
Collector
The summary phase operates on regions, not objects. Due to
compactions from previous collections, it is
typical that some portion of the
left side of each generation will be dense, containing mostly live
objects.
The amount of space that could be recovered from such dense regions is not worth
the cost of
compacting them. So the first thing the summary phase does is
examine the density of the regions,
starting with the leftmost one, until it
reaches a point where the space that could be recovered from a
region and
those to the right of it is worth the cost of compacting those regions. The
regions to the left
of that point are referred to as the dense prefix, and no
objects are moved in those regions. The regions
to the right of that point
will be compacted, eliminating all dead space. The summary phase
calculates
and stores the new location of the first byte of live data for
each compacted region. Note: The summary
phase is currently implemented as a
serial phase; parallelization is possible but not as important to
performance
as parallelization of the marking and compaction phases.
In the compaction
phase, the garbage collection threads use the summary data to identify regions
that
need to be filled, and the threads can independently copy data into the
regions. This produces a heap
that is densely packed on one end, with a
single large empty block at the other end.
When to Use the Parallel
Compacting Collector
As with the parallel collector, the parallel compacting
collector is beneficial for applications that are run
on machines with more
than one CPU. In addition, the parallel operation of old generation
collections
reduces pause times and makes the parallel compacting collector
more suitable than the parallel
collector for applications that have pause
time constraints. The parallel compacting collector might not
be suitable for
applications run on large shared machines (such as SunRays), where no single
application
should monopolize several CPUs for extended periods of time. On
such machines, consider either
decreasing the number of threads used for
garbage collection (via the –XX:ParallelGCThreads=n
command line option) or
selecting a different collector.
Parallel Compacting Collector
Selection
If you want the parallel compacting collector to be used, you must
select it by specifying the
command line option
-XX:+UseParallelOldGC.
Concurrent Mark-Sweep (CMS) Collector
For many
applications, end-to-end throughput is not as important as fast response time.
Young generation
collections do not typically cause long pauses. However, old
generation collections, though infrequent, can
impose long pauses, especially
when large heaps are involved. To address this issue, the HotSpot JVM includes
a
collector called the concurrent mark-sweep (CMS) collector, also known as
the low-latency collector.
Young Generation Collection Using the CMS
Collector
The CMS collector collects the young generation in the same manner
as the parallel collector.
Old Generation Collection Using the CMS
Collector
Most of the collection of the old generation using the CMS
collector is done concurrently with
the execution of the application.
A
collection cycle for the CMS collector starts with a short pause, called the
initial mark, that
identifies the initial set of live objects directly
reachable from the application code. Then,
during the concurrent marking
phase, the collector marks all live objects that are transitively
reachable
from this set. Because the application is running and updating reference fields
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 handle 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. Because the remark pause is more substantial than the initial
mark, multiple threads are run in
parallel to increase its efficiency.
At
the end of the remark phase, all live objects in the heap are guaranteed to have
been marked, so the
subsequent concurrent sweep phase reclaims all the
garbage that has been identified. Figure 7
illustrates the differences
between old generation collection using the serial
mark-sweep-compact
collector and the CMS collector.
11 Garbage Collectors
in the J2SE 5.0 HotSpot JVM Sun Microsystems, Inc.
Figure 7. Comparison
between serial and CMS old generation collection
Since some tasks, such as
revisiting objects during the remark phase, increase 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.
The CMS
collector is the only collector that is non-compacting. That is, after it frees
the space that was
occupied by dead objects, it does not move the live
objects to one end of the old generation. See Figure 8.
Figure 8. CMS
sweeping (but not compacting) of old generation
This saves time, but since
the free space is not contiguous, the collector can no longer use a
simple
pointer indicating the next free location into which the next object
can be allocated. Instead, it now
needs to employ free lists. That is, it
creates some number of lists linking together unallocated regions
of memory,
and each time an object needs to be allocated, the appropriate list (based on
the amount of
memory needed) must be searched for a region large enough to
hold the object As a result, allocations
into the old generation are more
expensive than they are with a simple bump-the-pointer technique.
This also
imposes extra overhead to young generation collections, as most allocations in
the old
generation occur when objects are promoted during young generation
collections.
Another disadvantage the CMS collector has is a requirement for
larger heap sizes than the other
collectors. Given that the application is
allowed to run during the marking phase, it can continue to
allocate memory,
thereby potentially continuing to grow the old generation. Additionally,
although the
collector guarantees to identify all live objects during a
marking phase, some objects may become
garbage during that phase and they
will not be reclaimed until the next old generation collection. Such
objects
are referred to as floating garbage.
Finally, fragmentation may occur due to
lack of compaction. To deal with fragmentation, the CMS
collector tracks
popular object sizes, estimates future demand, and may split or join free blocks
to
meet demand.
12 Garbage Collectors in the J2SE 5.0 HotSpot JVM Sun
Microsystems, Inc.
Stop-the-world pause
Stop-the-world pause
Serial
Mark-Sweep-Compact
Collector
Concurrent Mark-Sweep
Collector
Initial
Mark
Concurrent Mark
Remark
Concurrent Sweep
a) Start of
Sweeping
b) End of Sweeping
Unlike the other collectors, the CMS collector
does not start an old generation collection when the old
generation becomes
full. Instead, it attempts to start a collection early enough so that it can
complete
before that happens. Otherwise, the CMS collector reverts to the
more time-consuming stop-the-world
mark-sweep-compact algorithm used by the
parallel and serial collectors. To avoid this, the CMS
collector starts at a
time based on statistics regarding previous collection times and how quickly the
old
generation becomes occupied. The CMS collector will also start a
collection if the occupancy of the old
generation exceeds something called
the initiating occupancy. The value of the initiating occupancy is
set by the
command line option –XX:CMSInitiatingOccupancyFraction=n, where n is
a
percentage of the old generation size. The default is 68.
In summary,
compared to the parallel collector, the CMS collector decreases old generation
pauses—
sometimes dramatically—at the expense of slightly longer young
generation pauses, some reduction in
throughput, and extra heap size
requirements.
Incremental Mode
The CMS collector can be used in a mode in
which the concurrent phases are done incrementally. This
mode is meant to
lessen the impact of long concurrent phases by periodically stopping the
concurrent
phase to yield back processing to the application. The work done
by the collector is divided into small
chunks of time that are scheduled
between young generation collections. This feature is useful
when
applications that need the low pause times provided by the concurrent
collector are run on machines
with small numbers of processors (e.g., 1 or
2). For more information on usage of this mode, see the
“Tuning Garbage
Collection with the 5.0 Java? Virtual Machine” paper referred to in Section
9.
When to Use the CMS Collector
Use the CMS collector if your application
needs shorter garbage collection pauses and can afford to
share processor
resources with the garbage collector when the application is running. (Due to
its
concurrency, the CMS collector takes CPU cycles away from the application
during a collection cycle.)
Typically, applications that have a relatively
large set of long-lived data (a large old generation), and that
run on
machines with two or more processors, tend to benefit from the use of this
collector. An example
would be web servers. The CMS collector should be
considered for any application with a low pause time
requirement. It may also
give good results for interactive applications with old generations of a
modest
size on a single processor.
CMS Collector Selection
If you want
the CMS collector to be used, you must explicitly select it by specifying the
command line
option -XX:+UseConcMarkSweepGC. If you want it to be run in
incremental mode, also enable that
原文:http://www.cnblogs.com/godfatherback/p/3541945.html