...
Wiki Markup |
---|
Since JDK 1.2, the generational garbage collector has reduced memory allocation related costs to low levels, in many cases lower than C/C++. Improved garbage collection algorithms have reduced the cost of garbage collection so that it is proportional to the number of _live_ objects in the _younger generation_, rather than to the _total_ number of objects allocated since the last garbage collection. Generational garbage collection reduces garbage collection costs by grouping objects into generations. The _younger generation_ consists of short-lived objects. The GC performs a minor collection on the younger generation when it fills up with dead objects \[[Oracle 2010a|AA. Bibliography#Oracle 10a]\]. Improved garbage collection algorithms have reduced the cost of garbage collection so that it is proportional to the number of _live_ objects in the _younger generation_, rather than to the _total_ number of objects allocated since the last garbage collection. |
Wiki Markup |
---|
Note that objects in the _younger generation_ that persist for longer durations are _tenured_ and are moved to the _tenured generation_. Very few _younger generation_ objects continue to live through to the next garbage collection cycle; the rest become ready to be collected in the impending collection cycle \[[Oracle 2010a|AA. Bibliography#Oracle 10a]\]. |
With generational GCs, use of short-lived immutable objects is generally more efficient than use of long-lived mutable objects, such as object pools. Avoiding object pools improves the garbage collector's efficiency. Object pools bring additional costs and risks: they can create synchronization problems, and can require explicit management of deallocations, which risks problems with dangling pointers. Further, determining the correct amount of memory to provision reserve for an object pool can be difficult; this is especially problematic for mission critical code. Use of long-lived mutable objects remains appropriate in cases where allocation of objects is particularly expensive, such as when performing multiple joins across databases. Similarly, object pools are an appropriate design choice when the objects represent scarce resources such as thread pools and database connections.
...
This example also violates guideline FIO00-J. Defensively copy mutable inputs and mutable internal components and OBJ11-J. Defensively copy private mutable class members before returning their references.
Compliant Solution
This compliant solution uses a custom container called ImmutableHolder
. To aid garbage collection, it is recommended that short-lived ImmutableHolder
objects be created by passing Hashtable
instances to the constructor.
...
The allocation of large objects is expensive; further, the cost to initialize their fields is proportional to their size. Additionally, frequent allocation of large objects of different sizes can cause fragmentation issues or non-compacting collect operations.
Do Not Use Direct Buffers for Short Lived, Infrequently Used Objects
...
Reference nulling to "help the garbage collector" is unnecessary. It adds clutter to the code and can introduce subtle bugs. Assigning null
to local variables is also unnecessary; the Java Just-In-Time compiler (JIT) can perform an equivalent liveness analysis — ; in fact most implementations do this. A related bad practice is use of a finalizer to null
out references; see MET18-J. Avoid using finalizers for additional details.
...
The garbage collector can be explicitly invoked by calling the System.gc()
method. Even though the documentation says that it "Runs runs the garbage collector", there is no guarantee on as to when the garbage collector will actually run; in . In fact, the call only suggests that the GC will subsequently execute. Other reasons to avoid explicit invocation of the GC include:
...
In the Java Hotspot VM (default since JDK 1.2), System.gc()
forces an explicit garbage collection. Such calls can be buried deep within libraries and so they may be difficult to trace. To ignore the call in such cases, use the flag -XX:+DisableExplicitGC
. To avoid long pauses while doing performing a full GC, a less demanding concurrent cycle can may be invoked by specifying the flag -XX:ExplicitGCInvokedConcurrent
.
Exceptions
OBJ13-EX1: There are some exceptions to this recommendation. When an application goes through several phases such as an initialization and a ready phase, it may require heap compaction between phases. Given an uneventful period, System.gc()
may be invoked in such cases, provided that there is a suitable uneventful period between phases.
OBJ13-EX2: System.gc()
may also be invoked as a last resort in a catch
block that is attempting to recover from an OutOfMemoryError
.
...