Tips to Manage Garbage Collection in Java


With each evolution, garbage collectors get new improvements and advancements. However, garbage collections in Java face a common issue: unpredictable and redundant object allocations. Consider the following tips to improve your garbage collection in Java.

1.   Estimate Capacity of the Collections

All types of Java collections including extended and custom implementations take advantage of underlying object-based or primitive arrays. Due to the size immutability of arrays after allocation, when items are added to a collection, a new array can force the old array to get dropped.

Many implementations of collections attempt optimization of the re-allocation process and try to limit it an amortized restriction, whether or not the expected collection size is not given. To get the best results, give the collection its expected size during creation.

For instance, consider the following code.

public static List reverse(List < ? extends T > list) {

List answer = new ArrayList();

for (int x = list.size() – 1; x > = 0; x–) {

answer.add(list.get(x));

}

return answer;

}

In this method, a new array is allocated after which another list’s items fill it via a reverse order. In this code, optimization can be applied to the specific line which performs addition of items in the new list. Whenever an item is added, the list has to ensure that there are enough available slots in the underlying array so it can store the incoming item. If there is a free slot, then it can easily store it. Or else, it has to perform allocation of a new underlying array, move the content of the old array to the newer one, and then perform the addition of the new item. As a result, multiple arrays are allocated which are ultimately collected by the garbage collection.

In order to avoid these redundant and inefficient allocations, you can “inform” the array about the number of items it can store while creating it.

public static List reverse(List < ? extends T > list) {

 

List answer = new ArrayList(list.size());

 

for (int x = list.size() – 1; x > = 0; x–) {

answer.add(list.get(x));

}

return answer;

}

As a result, the first allocation from the constructor of the ArrayList is big enough to store the items of the list.size(), thus there is no need for reallocation of memory in the middle of an iteration.

2.   Compute Streams with a Direct Approach

While data is being processed like it is downloading from the network or read from the file, then it not uncommon to view the following instances.

byte[] fData = readFileToByteArray(new File(“abc.txt”));

As a result, the byte array a JSON object, XML document, or Protocol Buffer message can then be used for parsing. While working with bigger files or files having uncertain size, there are possibilities of exposure to OutOfMemoryErrors if buffer allocation of the complete file is not performed by the Java Virtual Machine.

In case, we assume that the data size can be managed, the above-mentioned pattern can lead on to generate considerable overhead for garbage collection because a huge blob is allocated on the heap for holding the data of the file.

There are better solutions to tackle this. One of them is the use of the relevant InputStream and use the parser directly before converting it into a byte array. Usually, all crucial libraries are known to have API exposure for direct streams parsing. For instance, consider the following code.

FileInputStream fstream =new FileInputStream(fileName);

MyProtoBufMessage message = MyProtoBufMessage.parseFrom(fstream);

3.    Make Use of Immutable Objects

Immutability brings a lot of benefits to the table. Perhaps, its biggest one is on the garbage collection. An object in which you cannot alter the fields after the construction of the project is known as an immutable object. For instance,

public class twoObjects {

private final Object a;

private final Object b;

public twoObjects(Object a, Object b) {

this.a = a;

this.b = b;

}

public Object getA() {

return a;

}

public Object getB() {

return b;

}

}

The instantiation of the above-mentioned class provides an immutable object in which all the fields are set as ‘final’ and cannot be altered.

Immutability means that objects which are referenced via an immutable container are generated prior to the container’s construction. In terms of garbage collection, the container and the reference have the same age.

Therefore, while working with cycles of garbage collections for young generations, the garbage collection can ignore the older generations’ immutable objects as they are unable to reference.

When there are lesser objects for scanning, it requires less memory and also saves up on garbage collection cycles, resulting in improved throughput.

4.   Leverage Specialized Primitive Collections

The standard collection library of Java is generic and convenient. It assists in using semi-static type binding in collections. This can be advantageous if, for instance, you have to use a string set or work with a map for strings lists.

The actual issue emerges when developers have to store a list contains “ints” or a map containing type double values. As it is not possible to use primitives with generic types, another option is the use of boxed type.

Such an approach consumes a lot of space because an Integer is an object having a 12-byte header and a 4-byte int field. In total each Integer item amounts to 16 bytes—four times the size of the similar primitive int data type. There is another issue that the object instances of these integers have to be assessed for garbage collection.

To resolve this issue, you can use the Trove collection library. It provides a few generics over specialized primitive collections that are memory efficient. For instance, rather than using the Map<Integer, Double>, you can use the TIntDoubleMap.

TIntDoubleMap mp = new TIntDoubleHashMap();

mp.put(6, 8.0);

mp.put(-2, 8.555);

The underlying implementation from Trove works with primitive arrays, hence no boxing occurs during the manipulation of collections and objects are not hold in the primitives’ place.

 

 

 

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s