Performance problems

Unnecessary instanceof operator

Not all Java compilers optimize unnecessary instanceof operators away, which results in additional costs at run time. This operation can also lead to dynamically unreachable code.

Solution: Remove the instanceof

Severity level: 2

Using the += operator on java.lang.String

The += operator for the java.lang.String type creates a new StringBuffer instance using the default constructor (which means an initial capacity of 16) under the cover, and then calling append() for each argument. It is more efficient to explicitly create and use StringBuffer for the same task, especially when there are multiple += operations on the same String variable.

Solution: don't use this operator repeatedly when the data is constructed, use one StringBuffer instead.

Severity level: 3

Using StringBuffer.setLength()

The init() method throws away its internal buffer and allocates a new one of size 16, even if it was created with a larger initial size. This can introduce unexpected performance problems as explained in the last section. In some implementations the original char array is overwritten with a zero value, which takes a lot more time for larger data sets than just throwing it away.

Solition: create a new StringBuffer instead of using StringBuffer.setLength()

Severity level: 3

Repeated calls to java.lang.Thread.currentThread

currentThread() is an expensive method call, because it is a native method and usually a kernel call. The HotSpot client compilers cannot inline such a method call, and have to use the interpreter to call into native code.

Solution: never use more than one call per method-body, and cache the result in a local variable. If possible, cache at a higher level and pass as a method argument.

Severity level: 3

Using String.getBytes() or String.getBytes(String) with ASCII data

Both methods perform quite expensive character conversion, which can be avoided for ASCII data.

Severity level: 3

Calling System.gc() or Runtime.gc()

Sun advises not call these methods in section 31 of this document.

Solution: remove this method call.

Severity level: 3

Using the default constructor of java.lang.StringBuffer

The StringBuffer default constructor creates a buffer that holds 16 characters by default. In many cases a significantly larger size is needed. By choosing to low a limit the class will perform frequent memory allocations and copies.

Solution: use the StringBuffer(int) constructor with an estimate of the final size

Severity level: 4

StringBuffer fields

StringBuffers can grow quite large, and can become a memory sink if the owning class has a long life time.

Solution: null out the reference as soon as possible

Severity level: 4

Using the java.lang.String(java.lang.String) constructor

String instances are immutable in the Java programming language. It is not necessary to create a new String object from an existing String, such as when given as an argument in a method call. This only results in a performance penalty due to object creation, more memory usage, and additional bookkeeping during garbage collection.

Solution: remove the call to this constructor

Severity level: 4

Using the java.lang.Boolean(boolean) constructor

Although object creation is fast in most 1.3 and 1.4 VMs, using Boolean.TRUE and Boolean.FALSE has advantages in the following cases. When a lot of long-lived objects are created, there is a additional cost for the garbage-collector once the objects leave the Eden space, because the data needs to be tracked and copied. Using the constants lowers the load.

Solution: use Boolean.TRUE and Boolean.FALSE, or Boolean.valeof(boolean)

Severity level: 4

Unnecessary casts of a type to the same or a supertype

Not all Java compilers optimize unnecessary casts away, which results in additional costs at run time.

Solution: Remove the cast.

Severity level: 4

Creation of zero-length arrays, instead of using a constant

Such arrays are immutable, and don't need to be recreated. When a lot of long-lived objects are created, there is a additional cost for the garbage-collector once the objects leave the Eden space, because the data needs to be tracked and copied. Using a constants lowers the load.

Solution: create a constant zero length array, and use it instead of creating new arrays.

Severity level: 5

Assigning the default initialization values to fields

Every field is assigned the value zero or null when a class is instantiated by the virtual machine. Explicitly assigning these values is unnecessary, and can make debugging more painful, because the assignments count as a statement.

Solution: don't use assign the default value to a field

Severity level: 5