...
Use Short-Lived Immutable Objects
Since JDK 1.2, the generational GC has reduced memory allocation costs to low levels, in many cases lower than in C or C++. 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. References#Oracle 10]\]. 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 number of objects allocated since the last garbage collection.unmigrated-wiki-markup Wiki Markup
Note that objects in the younger generation that persist for longer durations are _tenured_ and are moved to the _tenured generation_. 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. References#Oracle 10]\].
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 GCâs efficiency. Object pools bring additional costs and risks: they can create synchronization problems and can require explicit management of deallocations, possibly creating problems with dangling pointers. Further, determining the correct amount of memory to reserve for an object pool can be difficult, especially for mission-critical code. Use of long-lived mutable objects remains appropriate when allocation of objects is particularly expensive (for example, 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.
...
Code Block | ||
---|---|---|
| ||
int[] buffer = new int[100]; doSomething(buffer); buffer = null // No need to explicitly assign null |
Compliant Solution
Program logic occasionally requires tight control over the lifetime of an object referenced from a local variable. In the unusual cases where such control is necessary, use a lexical block to limit the scope of the variable because the GC can collect the object immediately when it goes out of scope \[ [Bloch 2008|AA. References#Bloch 08]\]. Wiki Markup
This compliant solution uses a lexical block to control the scope, and consequently the lifetime, of the buffer
object.
...
Code Block | ||
---|---|---|
| ||
class DataElement { public static final DataElement NULL = createSentinel(); // dead flag removed // other fields private static final DataElement createSentinel() { // allocate a sentinel object, setting all its fields // to carefully chosen "do nothing" values } } // elsewhere ArrayList longLivedList = new ArrayList<DataElement>(...); // processing that renders an element irrelevant // set the reference to the irrelevant DataElement to // the NULL object longLivedList.set(someIndex, NULL); |
...
When using this pattern, the {{NULL
}} object must be a singleton and must be final. It may be either public or private, depending on the overall design of the {{DataElement
}} class. The state of the {{NULL
}} object should be immutable after creation; immutability can be enforced either by using {{final
}} fields or by explicit code in the methods of the {{DataElement
}} class. See \ [[Grand 2002|AA. References#Grand 02]\] Chapter 8, âBehavioral Patterns, the Null Object,â for additional information on this design pattern.
Do Not Explicitly Invoke the Garbage Collector
...
CWE ID 405, âAsymmetric Resource Consumption (Amplification)â |
Bibliography
...
[ [API 2006AA. References#API 06]] | Class | ]]></ac:plain-text-body></ac:structured-macro> | <ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="291fa687-3543-4c24-9892-5169bc47c7b8"><ac:plain-text-body><![CDATA[ | |
[[Bloch 2008AA. References#Bloch 08] ] | Item 6: âEliminate obsolete object referencesâ]]></ac:plain-text-body></ac:structured-macro> | |||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1760585a-3f26-49e5-96c1-b5b13eb73333"><ac:plain-text-body><![CDATA[ | [ [Coomes 2007AA. References#Coomes 07]] | Garbage Collection Concepts and Programming Tips | ]]></ac:plain-text-body></ac:structured-macro> | <ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="af378dc4-45ca-4f2d-8969-f279c9fb5e64"><ac:plain-text-body><![CDATA[ |
[ [Goetz 2004AA. References#Goetz 04]] | Java theory and practice: Garbage collection and performance | ]]></ac:plain-text-body></ac:structured-macro> | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c23aa86d-bdeb-495c-a777-7bdc0358dead"><ac:plain-text-body><![CDATA[ | [[Lo 2005AA. References#Lo 05] ] | Security Issues in Garbage Collection ]]></ac:plain-text-body></ac:structured-macro> |
...
OBJ03-J. Do not mix generic with nongeneric raw types in new code 04. Object Orientation (OBJ) 05. Methods (MET)