Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using final for variables in Java improve garbage collection?

Today my colleagues and me have a discussion about the usage of the final keyword in Java to improve the garbage collection.

For example, if you write a method like:

public Double doCalc(final Double value) {    final Double maxWeight = 1000.0;    final Double totalWeight = maxWeight * value;    return totalWeight;   } 

Declaring the variables in the method final would help the garbage collection to clean up the memory from the unused variables in the method after the method exits.

Is this true?

like image 430
Goran Martinic Avatar asked Nov 20 '08 21:11

Goran Martinic


People also ask

Does final in Java improve performance?

Classes and MethodsThere are no reported performance benefits of applying final to classes and methods.

What are best practices on garbage collection in Java?

The best approach to tuning Java garbage collection is setting flags on the JVM. Flags can adjust the garbage collector to be used (e.g. Serial, G1, etc.), the initial and maximum size of the heap, the size of the heap sections (e.g. Young Generation, Old Generation), and more.

What causes high garbage collection in Java?

Excessive garbage collection activity can occur due to a memory leak in the Java application. Insufficient memory allocation to the JVM can also result in increased garbage collection activity. And when excessive garbage collection activity happens, it often manifests as increased CPU usage of the JVM!

How to make an object eligible for garbage collection in Java?

How to make object eligible for garbage collection in Java? An object is eligible to be garbage collected if its reference variable is lost from the program during execution.Sometimes they are also called unreachable objects. What is reference of an object? The new operator dynamically allocates memory for an object and returns a reference to it.

What are the advantages and disadvantages of garbage collection in Java?

The advantages of Garbage Collection in Java are: It makes java memory-efficient because the garbage collector removes the unreferenced objects from heap memory. It is automatically done by the garbage collector (a part of JVM), so we don’t need extra effort.

Does the final keyword affect the garbage collector?

Of course, as pointed by many, the final keyword does not reallly affect the garbage collector, but it does guarantee that the reference will never be changed into a younger object if this object survives the minor collections and makes it to the older heap. Articles: IBM on garbage collection: history, in the hotspot JVMand performance.

How does the JVM garbage collector affect performance?

When a long lived (old generation) object gets a reference to a new object, that reference must be explicitly tracked by the garbage collector (see article from IBM on the hotspot JVM collector), actually affecting the GC performance.


2 Answers

Here's a slightly different example, one with final reference-type fields rather than final value-type local variables:

public class MyClass {     public final MyOtherObject obj;  } 

Every time you create an instance of MyClass, you'll be creating an outgoing reference to a MyOtherObject instance, and the GC will have to follow that link to look for live objects.

The JVM uses a mark-sweep GC algorithm, which has to examine all the live refereces in the GC "root" locations (like all the objects in the current call stack). Each live object is "marked" as being alive, and any object referred to by a live object is also marked as being alive.

After the completion of the mark phase, the GC sweeps through the heap, freeing memory for all unmarked objects (and compacting the memory for the remaining live objects).

Also, it's important to recognize that the Java heap memory is partitioned into a "young generation" and an "old generation". All objects are initially allocated in the young generation (sometimes referred to as "the nursery"). Since most objects are short-lived, the GC is more aggressive about freeing recent garbage from the young generation. If an object survives a collection cycle of the young generation, it gets moved into the old generation (sometimes referred to as the "tenured generation"), which is processed less frequently.

So, off the top of my head, I'm going to say "no, the 'final' modifer doesn't help the GC reduce its workload".

In my opinion, the best strategy for optimizing your memory-management in Java is to eliminate spurious references as quickly as possible. You could do that by assigning "null" to an object reference as soon as you're done using it.

Or, better yet, minimize the size of each declaration scope. For example, if you declare an object at the beginning of a 1000-line method, and if the object stays alive until the close of that method's scope (the last closing curly brace), then the object might stay alive for much longer that actually necessary.

If you use small methods, with only a dozen or so lines of code, then the objects declared within that method will fall out of scope more quickly, and the GC will be able to do most of its work within the much-more-efficient young generation. You don't want objects being moved into the older generation unless absolutely necessary.

like image 183
benjismith Avatar answered Sep 26 '22 10:09

benjismith


Declaring a local variable final will not affect garbage collection, it only means you can not modify the variable. Your example above should not compile as you are modifying the variable totalWeight which has been marked final. On the other hand, declaring a primitive (double instead of Double) final will allows that variable to be inlined into the calling code, so that could cause some memory and performance improvement. This is used when you have a number of public static final Strings in a class.

In general, the compiler and runtime will optimize where it can. It is best to write the code appropriately and not try to be too tricky. Use final when you do not want the variable to be modified. Assume that any easy optimizations will be performed by the compiler, and if you are worried about performance or memory use, use a profiler to determine the real problem.

like image 37
Aaron Avatar answered Sep 22 '22 10:09

Aaron