java 垃圾回收 null_java-变量= null是否将其设置为垃圾回收

java-变量= null是否将其设置为垃圾回收

帮助我与同事解决争议:在Java中将变量或集合设置为null是否有助于垃圾回收并减少内存使用? 如果我有一个运行时间较长的程序,并且每个函数都可能被迭代调用(可能数千次):在将值返回给父函数之前将其中的所有变量设置为null是否有助于减少堆大小/内存使用量?

8个解决方案

59 votes

那是旧的表演传奇。 在1.0天之内确实如此,但是对编译器和JVM进行了改进以消除这种需求(如果有的话)。 如果您有兴趣,这篇出色的IBM文章将详细介绍以下内容:Java理论与实践:垃圾回收和性能

sblundy answered 2020-01-21T04:33:00Z

7 votes

从文章:

在一种情况下,显式空值的使用不仅有帮助,而且实际上是必需的,这就是说,对对象的引用的范围比程序规范所使用或认为的范围更广。 这包括使用静态或实例字段存储对临时缓冲区的引用而不是局部变量的情况,或使用数组存储可能在运行时仍可访问但不能通过程序的隐含语义访问的引用。

翻译:不再需要的“显式null”持久对象。 (如果需要。“几乎是必需的”声明太强了吗?)

Pete answered 2020-01-21T04:33:30Z

5 votes

Java VM规范

12.6.1实施最终确定   每个对象可以通过两个属性来表征:它可以是可到达的,终结器可到达的或不可到达的,并且它也可以是未终结的,终结的或终结的。

可达对象是可以从任何活动线程进行任何潜在的连续计算中访问的任何对象。 可以设计程序的优化转换,以将可到达的对象数量减少到少于天真的被认为可到达的对象数量。 例如,编译器或代码生成器可能会选择设置将不再用于为null的变量或参数,以使此类对象的存储可能会尽快收回。

讨论区

如果对象字段中的值存储在寄存器中,则会发生这种情况的另一个示例。 然后,程序可能会访问寄存器而不是对象,而不再访问对象。 这意味着该对象是垃圾。

如果对象可以参与任何潜在的连续计算,则该对象是可到达的。 因此,如果您的代码引用了局部变量,而没有其他引用,那么您可以通过将其设置为null来导致对象被收集。 这将给出空指针异常,或者更改程序的行为,或者如果两者都不执行,则首先不需要该变量。

如果要使字段或数组元素为空,那么这对于某些应用程序可能是有意义的,这将导致更快地回收内存。 一旦案例创建了一个大数组来替换类中某个字段所引用的现有数组-如果在创建替换之前该字段为null,则可以减轻对内存的压力。

Java的另一个有趣的功能是作用域不出现在类文件中,因此作用域与可达性无关。 这两个方法创建相同的字节码,因此VM根本看不到所创建对象的范围:

static void withBlock () {

int x = 1;

{

Object a = new Object();

}

System.out.println(x+1);

}

static void withoutBlock () {

int x = 1;

Object a = new Object();

System.out.println(x+1);

}

Pete Kirkham answered 2020-01-21T04:34:23Z

3 votes

不必要。 当不再有活动线程持有对该对象的引用时,该对象就可以进行垃圾回收。

当方法返回时,局部变量超出范围,将局部变量设置为null根本没有意义-变量始终消失,并且如果没有其他保存引用的对象是变量所引用的对象,则这些对象将变为 有资格进行垃圾收集。

关键不是仅查看变量,而是查看这些变量引用的对象,并找出程序在何处引用了这些对象。

Jesper answered 2020-01-21T04:34:53Z

2 votes

它对局部变量没有用,但是可以用于/需要清除不再需要的实例变量(例如,初始化后)。

(是的,我知道如何应用Builder模式...)

Rhangaun answered 2020-01-21T04:35:17Z

1 votes

只有在这样的情况下才有意义:

public void myHeavyMethod() {

List hugeList = loadHugeListOfStuff(); // lots of memory used

ResultX res = processHugeList(hugeList); // compute some result or summary

// hugeList = null; // we are done with hugeList

...

// do a lot of other things that takes a LOT of time (seconds?)

// and which do not require hugeList

...

}

我想,在这里取消hugeList = null行的注释可能会有所帮助。

但是重写该方法肯定会更有意义(也许重构为两个,或指定内部范围)。

leonbloy answered 2020-01-21T04:35:46Z

0 votes

将对象引用设置为null只会使其有资格进行垃圾回收。它不一定释放内存,这取决于垃圾收集器的运行时间(取决于JVM)。当垃圾收集器运行时,它通过仅删除符合垃圾收集条件的对象来释放堆。

Saurabh answered 2020-01-21T04:36:06Z

-4 votes

有一个很好。 将对象设置为null时,有可能在立即GC周期中更快地垃圾回收对象。 但是没有保证在给定时间收集对象垃圾的机制。

Java Guy answered 2020-01-21T04:36:27Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值