又见【不使用的对象应手动赋值为null】

今天看到 一篇文章
,讨论 【不使用的对象应手动赋值为null】
这件事。

文中给了这样一个例子:

public static void main(String[] args) {
    if (true) {
        byte[] placeHolder = new byte[64 * 1024 * 1024];
        System.out.println(placeHolder.length / 1024);
    }
    System.gc();
}

执行结果:
65536
[GC 68239K->65952K(125952K), 0.0014820 secs]
[Full GC 65952K->65881K(125952K), 0.0093860 secs]

上面这段代码执行gc后内存占用没有降下来,没有把placeHolder回收掉。

而下面这段代码就会被回收:

public static void main(String[] args) {
    if (true) {
        byte[] placeHolder = new byte[64 * 1024 * 1024];
        System.out.println(placeHolder.length / 1024);
        placeHolder = null;
    }
    System.gc();
}

执行结果:
65536
[GC 68239K->65952K(125952K), 0.0014910 secs]
[Full GC 65952K->345K(125952K), 0.0099610 secs]

文章认为原因是 触发GC时,main()方法的运行时栈中,还存在有对args和placeHolder的引用,GC判断这两个对象都是存活的,不进行回收。

事实真的是这样吗?

我们不妨看看第一段代码的字节码大家就明白了。

 0: ldc           #2                  // int 67108864
 2: newarray       byte
 4: astore_1
 5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 8: aload_1
 9: arraylength
10: sipush        1024
13: idiv
14: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
17: invokestatic  #5                  // Method java/lang/System.gc:()V
20: return

从字节码可以看到, if(true)
编译时被优化掉了,代码相当于变成了下面这样,placeHolder的作用域变大了,所有在GC时不会被回收。

public static void main(String[] args) {
    byte[] placeHolder = new byte[64 * 1024 * 1024];
    System.out.println(placeHolder.length / 1024);
    System.gc();
}

现在我们来换个写法,不让if条件被优化掉:

public static void main(String[] args) {
    if (args.length == 0) {
        byte[] placeHolder = new byte[64 * 1024 * 1024];
        System.out.println(placeHolder.length / 1024);
    }
    System.gc();
}

执行结果:【省略了部分无关的GC输出】
65536
[GC (System.gc()) 70793K->66152K(251392K), 0.0008739 secs]
[Full GC (System.gc()) 66152K->458K(251392K),0.0041778 secs]

可以看到,GC后placeHolder被回收了。

关于赋不赋值为null这件事,看个人编码习惯,我一般不喜欢做这些多余的操作,实际对GC也不会产生什么影响。那篇文章后面关于局部变量表重用的讨论是没问题的,但关于赋值为null因为使用了不妥当的例子而得到了错误的结论。

原文 

https://blog.darkness463.top/2019/11/19/objects-set-null/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 又见【不使用的对象应手动赋值为null】

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址