在Java中使用final变量可以改善垃圾收集吗? [英] Does using final for variables in Java improve garbage collection?

查看:104
本文介绍了在Java中使用final变量可以改善垃圾收集吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我和我的同事们讨论了在Java中使用 final 关键字来改善垃圾收集。



例如,如果您编写如下方法:

  public Double doCalc(final Double value)
{
final Double maxWeight = 1000.0;
final DoubleWeight = maxWeight * value;
返回totalWeight;

在方法 final 中声明变量c $ c>会在方法退出后帮助垃圾回收从方法中未使用的变量中清理内存。



这是真的吗?

解决方案

下面是一个稍微有点不同的例子,其中一个使用最终引用类型字段而不是最终值类型局部变量:

  public class MyClass {

public final MyOtherObject obj;


$ / code>

每次创建MyClass的实例时,都会创建一个MyOtherObject实例的外向引用,并且GC必须遵循该链接来查找活动对象。



JVM使用标记扫描GC算法,必须检查GC根位置(如当前调用堆栈中的所有对象)中的所有实参。每个活动对象都被标记为活着,并且活动对象引用的任何对象也被标记为活着。

标记阶段完成后, GC扫过堆,为所有未标记的对象释放内存(并为剩余的活动对象压缩内存)。

此外,重要的是要认识到Java堆记忆被划分为年轻一代和老一代。所有对象最初都分配给年轻一代(有时称为幼儿园)。由于大多数物体寿命短暂,GC更积极地释放年轻一代的近期垃圾。如果一个物体在年轻一代的收集周期中存活下来,它就会进入老一代(有时称为老一代),这种情况的处理较少。

<因此,我想说,不,最终'修改者不会帮助GC减少工作量。



在我看来,在Java中优化内存管理的最佳策略是尽可能快地消除虚假引用。你可以做到这一点,只要你完成使用它,就为对象引用分配null。



或者更好的做法是最小化每个声明范围的大小。例如,如果您在1000行方法的开头声明一个对象,并且对象在该方法的作用域(最后一个关闭大括号)关闭之前一直处于活动状态,则对象可能会保持活动状态的时间长得多必要的。



如果使用小方法,只需十几行代码,那么在该方法中声明的对象将更快地超出范围, GC将能够在效率更高的年轻一代中完成大部分工作。除非绝对必要,否则您不希望对象移动到前一代。


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?

解决方案

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.

这篇关于在Java中使用final变量可以改善垃圾收集吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆