Does using final for variables in Java improve gar

2019-01-08 05:58发布

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?

14条回答
你好瞎i
2楼-- · 2019-01-08 06:07

All method and variable can be overridden bydefault in subclasses.If we want to save the subclasses from overridig the members of superclass,we can declare them as final using the keyword final. For e.g- final int a=10; final void display(){......} Making a method final ensures that the functionality defined in the superclass will never be changed anyway. Similarly the value of a final variable can never be changed. Final variables behaves like class variables.

查看更多
该账号已被封号
3楼-- · 2019-01-08 06:14

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.

查看更多
对你真心纯属浪费
4楼-- · 2019-01-08 06:16

Some points to clear up:

  • Nulling out reference should not help GC. If it did, it would indicate that your variables are over scoped. One exception is the case of object nepotism.

  • There is no on-stack allocation as of yet in Java.

  • Declaring a variable final means you can't (under normal conditions) assign a new value to that variable. Since final says nothing about scope, it doesn't say anything about it's effect on GC.

查看更多
▲ chillily
5楼-- · 2019-01-08 06:16

The only time I prefer declaring local variables as final is when:

  • I have to make them final so that they can be shared with some anonymous class (for example: creating daemon thread and let it access some value from enclosing method)

  • I want to make them final (for example: some value that shouldn't/doesn't get overridden by mistake)

Does they help in fast garbage collection?
AFAIK a object becomes a candidate of GC collection if it has zero strong references to it and in that case as well there is no guarantee that they will be immediately garbage collected . In general, a strong reference is said to die when it goes out of scope or user explicitly reassign it to null reference, thus, declaring them final means that reference will continue to exists till the method exists (unless its scope is explicitly narrowed down to a specific inner block {}) because you can't reassign final variables. So I think w.r.t Garbage Collection 'final' may introduce a unwanted possible delay.

查看更多
爷、活的狠高调
6楼-- · 2019-01-08 06:17

The only thing that I can think of is that the compiler might optimize away the final variables and inline them as constants into the code, thus you end up with no memory allocated.

查看更多
放荡不羁爱自由
7楼-- · 2019-01-08 06:25

absolutely, as long as make object's life shorter which yield great benefit of memory management, recently we examined export functionality having instance variables on one test and another test having method level local variable. during load testing, JVM throws outofmemoryerror on first test and JVM got halted. but in second test, successfully able to get the report due to better memory management.

查看更多
登录 后发表回答