Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: moderate re-write

From a security point of view, Java's garbage collection feature provides significant benefits over traditional languages such as C and C++. The garbage collector (GC) is designed to automatically reclaim unreachable memory and as a result avoid memory leaks. While 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 as or well as abnormally prolonged object retention.

For example, some versions of the GC needs may need to halt all executing threads in order to keep up with the incoming allocation requests that command trigger increased heap management in terms of space allocationactivity. 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 source perform memory allocations in a way that keeps increases resource consumption (such as CPU, battery power, memory) high without triggering an OutOfMemoryError.

Writing garbage collection friendly code helps restrict many attack avenues. The Many of the best practices have been collated and are enumerated below.

Use Short-Lived Immutable Objects

Wiki Markup
Since JDK 1.2, the new generational garbage collector has reduced memory allocation related costs to minimallow levels, in evenmany cases lesserlower than C/C++. DeallocationImproved hasgarbage alsocollection becomealgorithms cheaperhave such thatreduced the cost of garbage collection  so that it is commensurateproportional withto the number of _live_ objects in the _younger generation_, andrather than notto the _total_ number of objects allocated since the last run. Memory is managed in generations to optimize the collectiongarbage collection. Generational garbage collection reduces garbage collection costs by grouping objects into generations. The _younger generation_ consists of short-lived objects. A The GC performs a minor collection on the younger generation is performed when it fills up with dead objects \[[Oracle 2010a|AA. Bibliography#Oracle 10a]\].  

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 it is advantageous to , use of short-lived immutable objects instead is generally more efficient than use of long-lived mutable objects. Object pools are examples of the latter and should be avoided to increase , such as object pools. Avoiding object pools improves the garbage collector's efficiency. Moreover, object pools Object pools bring additional costs and risks: they can create synchronization problems, deallocations have to be managed explicitly leading to dangers of dangling pointers, and the size of the pool plays a dominant role in mission critical code. Exceptions to this recommendation can be made when the allocation takes longer in comparisonand can require explicit management of deallocations, which risks problems with dangling pointers. Further, determining the correct amount of memory to provision 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 or when using objects that . Similarly, object pools are an appropriate design choice when the objects represent scarce resources such as thread pools and database connections.

...

Compliant Solution

This compliant solution highlights 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.

...

Avoid Large Objects

The allocation for of large objects is expensive and ; further, the initialization cost to initialize their fields is proportional to their size. Sometimes Additionally, frequent allocation of large objects of different sizes can cause fragmentation issues or non compacting collect.

...

The new IO classes (NIO) in java.nio allow the creation and use of direct buffers. These buffers tremendously increase throughput for repeated IO activities, however. However, their creation and reclamation for one-time use is more expensive than that for heap-based non-direct buffers. This is because , because direct buffers are managed using OS specific native code is used to manage them. An OutOfMemoryError may result if large objects are allocated frequently using this technique. This added management cost makes direct buffers an poor choice for single-use or infrequently used cases. Direct buffers are also not subject to Java's garbage collector which may can cause memory leaks. Frequent allocation of large direct buffers can cause an OutOfMemoryError.

Noncompliant Code Example

This noncompliant code example uses a short-lived local object buffer. The buffer , which is allocated in non-heap memory and is not garbage collected.

...

Reference nulling to "help the garbage collector" is unnecessary. In fact, it just It adds clutter to the code and sometimes introduces can introduce subtle bugs. Assigning null to local variables is also not very useful as unnecessary; the Java Just-In-Time compiler (JIT) can equivalently do a perform an equivalent liveness analysis — most implementations do this. A related bad practice is to use of a finalizer to null out references. This practice can cause a huge performance hit; see OBJ08-J. Avoid using finalizers for additional details.

Noncompliant Code Example

...

Wiki Markup
This compliant solution adds a improveslexical byblock narrowingto downlimit the scope of the variable {{buffer}} so; that the garbage collector collectscan collect the object asimmediately soon aswhen it goes out of scope \[[Bloch 2008|AA. Bibliography#Bloch 08]\].

...

Array based data structures such as ArrayLists are exceptions because the programmer has may be required to explicitly set a few of the individual array elements to null to indicate their absence or demise.

Long-Lived Objects Containing Short-Lived Objects

Always remove short-lived objects from the long-lived container objects when the task is over. For example, objects attached to a java.nio.channels.SelectionKey object must be removed when they are no longer needed. Doing so reduces the possibility of memory leaks.

...

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 on when the garbage collector will actually run because ; in fact, the call only suggests that it the GC will subsequently execute. Other reasons include the followingto avoid explicit invocation of the GC include:

  • Irresponsible use of this feature can severely degrade system performance as the garbage collector would not wait by triggering garbage collection at inopportune moments, rather than waiting until ripe periods when it is safe to garbage collect without interrupting significant interruption of the program's execution significantly.
  • The application does not have enough information available lacks sufficient information on when to call System.gc().

In the Java Hotspot VM (default since JDK 1.2), System.gc() does forces an explicit garbage collection. Sometimes these Such calls are can be buried deep within libraries and are hard difficult to trace. To ignore the call in such cases, use the flag -XX:+DisableExplicitGC. To avoid long pauses while doing a full GC, a less demanding concurrent cycle can be invoked by specifying the flag -XX:ExplicitGCInvokedConcurrent.

There are some exceptions to this recommendation. The garbage collector can be explicitly called when the When an application goes through several phases like the such as an initialization and the a ready phase. The heap needs to be compacted between these , it may require heap compaction between phases. Given an uneventful period, System.gc() may be explicitly invoked in this case. Also, it may such cases, provided that there is a suitable uneventful period between phases. System.gc() may also be invoked as a last resort in a catch block that is attempting to recover from an OutOfMemoryError.

...

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

OBJ13-J

low

likely

high

P3

L3

...

TODO

Related Vulnerabilities

GERONIMO-4574

...

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]\] 
\[[Lo 2005|AA. Bibliography#Lo 05]\] 
\[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 6: "Eliminate obsolete object references"
\[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID 405|http://cwe.mitre.org/data/definitions/405.html] "Asymmetric Resource Consumption (Amplification)"

...