Java's garbage collection feature provides significant benefits from a security perspective over non-garbage collected languages such as C and C++. The garbage collector (GC) is designed to automatically reclaim unreachable memory and avoid memory leaks. Although it is quite adept at performing this task, a malicious attacker can nevertheless launch a denial of service (DoS) attack, for example, by inducing abnormal heap memory allocation or abnormally prolonged object retention. For example, some versions of the GC could need to halt all executing threads to keep up with incoming allocation requests that trigger increased heap management activity. System throughput rapidly diminishes in this scenario. Real-time systems, in particular, are vulnerable to a more subtle slow heap exhaustion DoS attack, perpetrated by stealing CPU cycles. An attacker can perform memory allocations in a way that increases the consumption of resources (such as CPU, battery power, and memory) without triggering an OutOfMemoryError
. Writing garbage-collection-friendly code helps restrict many attack avenues.
...
Wiki Markup |
---|
Since JDK 1.2, the generational garbage collector has reduced memory allocation costs to low levels, in many cases lower than 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. 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_. 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, 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 in cases where 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 | ||
---|---|---|
| ||
ByteBuffer rarelyUsedBuffer = ByteBuffer.allocate(8192); // use rarelyUsedBuffer once ByteBuffer heavilyUsedBuffer = ByteBuffer.allocateDirect(8192); // use heavilyUsedBuffer many times |
Do
...
Not Attempt to "
...
Help the
...
Garbage Collector" by
...
Setting Local Reference Variables to Null
Setting local reference variables to null
to "help the garbage collector" is unnecessary. It adds clutter to the code and can introduce subtle bugs. Java Just-In-Time compilers (JITs) 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 guideline "MET18-J. Avoid using finalizers" for additional details.
...
Wiki Markup |
---|
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 garbage collector can collect the object immediately when it goes out of scope \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. |
This compliant solution uses a lexical block to control the scope - and, consequently, the lifetime - of the buffer
object.
Code Block | ||
---|---|---|
| ||
{ // limit the scope of buffer
int[] buffer = new int[100];
doSomething(buffer);
}
|
...
The garbage collector cannot collect the dead DataElement
object until it becomes unreferenced. Note that all methods that operate on objects of class DataElement
must check whether the instance in hand is dead.
Compliant Solution (Set
...
Reference to null)
In this compliant solution, rather than use a dead flag, the programmer assigns null
to ArrayList
elements that have become irrelevant.
...
Note that all code that operates on the longLivedList
must now check for list entries that are null.
Compliant Solution (Use Null Object
...
Pattern)
This compliant solution avoids the problems associated with intentionally null references by use of a singleton sentinel object. This is known as the Null Object pattern (also known as the Sentinel pattern). When feasible, programmers should choose this design pattern over the explicit null reference values.
...
The garbage collector can be explicitly invoked by calling the System.gc()
method. Even though the documentation says that it "runs the garbage collector," , there is no guarantee as to when the garbage collector will actually run. In fact, the call only suggests that the GC will subsequently execute.
- Irresponsible use of this feature can severely degrade system performance by triggering garbage collection at inopportune moments , rather than waiting until ripe periods when it is safe to garbage collect without significant interruption of the program's execution.
...
Wiki Markup |
---|
\[[API 2006|AA. Bibliography#API 06]\] Class {{System}} \[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 6: "Eliminate obsolete object references" \[[Commes 2007|AA. Bibliography#Commes 07]\] Garbage Collection Concepts and Programming Tips \[[Goetz 2004|AA. Bibliography#Goetz 04]\] Java theory and practice: Garbage collection and performance \[[Lo 2005|AA. Bibliography#Lo 05]\] Security Issues in Garbage Collection \[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID -405|http://cwe.mitre.org/data/definitions/405.html] "Asymmetric Resource Consumption (Amplification)" |
...