Java对象不使用时赋值null的意义详解

先看代码

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

idea配置gc日志打印

运行上面的代码,载图gc日志

现在我们修改上面的测试代码,将placeHolder置为null

public class TestDemo1 {
  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();
  }
}

再次运行程序,查看gc日志

由以上载图日志可以明显看到二者差别,所以不用对象置为null还是很有意义的。

为啥会造成二者的区别呢?

这还得从jvm认定垃圾的机制:可达性分析说起。

说起这个可达性,首先就得说到根,而“本地变量表”恰恰就可以看成是根。

上面两段代码本地变量表是不一样的。

先看第一段代码,就是placeHolder没有置null的“本地变量表 ”

使用javap -v TestDemo1.class

可以看到placeHolder还在本地变量表中,而且它占用slot槽1号位置, 所以jvm认为它还是活着的。

然后,我们再看placeHolder =null这段代码的"本地变量表"的情况,其实它与上面一样,看不出啥差别。

但是如果我们在placeHolder后面再声明一个变量

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

可以看到name这个变量名将slot槽1号位置占用了,是否可以说明placeHolder没啥用了呢

而且这段代码与placeHolder = null的gc日志完全一样。那么应该可以说明,我们声明的这个String name = "admin" 断开了栈中placeHolder与堆中实例之间关系。

而placeHolder =null应该也有这个功能。

总结:代码离开变量作用域时,并不会自动切断其与堆的联系。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java中对null进行强制类型转换的方法

    今天很好奇,对null进行强转会不会抛错.做了如下测试得到的结果是,如果把null强转给对象,是不会抛异常的,本身对象是可以为null的.但是如果是基本类型,比如 int i = (Integer)obj的强转,其实内部会调用intvalue方法去赋值给基本类型,所以这时候是会报错的. 代码如下 Object obj = null; Integer s1 = (Integer)obj; 上面能正常执行,即把null赋值给一个对象或者强行类型转换赋值给对象都是没有问题的.如果s1是 int的基本类

  • 详解Java去除json数据中的null空值问题

    1.描述 @JsonInclude(JsonInclude.Include.NON_NULL)标记是jackson包提供的json序列化方法,已经集成于Springboot2.0中,此方法的配置意在可以对实体json序列化的时候进行对应的数值处理. 2.使用 用注解的方式放在标记类或者属性 @JsonInclude(JsonInclude.Include.NON_NULL) public class User implements Serializable { private String us

  • java.lang.NullPointerException 如何处理空指针异常的实现

    当应用程序试图null在需要对象的情况下使用时抛出.这些包括: 调用null对象的实例方法. 访问或修改null对象的字段. 把长度null当作一个数组. 像访问或修改null阵列一样访问或修改插槽. 投掷null就好像它是一个Throwable 价值. 应用程序应该抛出此类的实例来指示null对象的其他非法使用. NullPointerException对象可以由虚拟机构造,就像抑制被禁用和/或堆栈跟踪不可写一样. 为什么我们需要空值? 如前所述,nullJava是一种特殊的值. 它在编码某些

  • javascrit中undefined和null的区别详解

    1.Undefined Undefined 类型只有一个值,即特殊的undefined.根据工作中总结,只要有这几种情况下会出现undefined. 1.定义变量,但是没有初始化时,如var a: 2.调用某个函数时,实参个数小于形参个数时,未实参化的形参在函数调用过程中的值是undefined: 3.调用某个对象还没有添加的属性时,也会返回undefined: var obj={} console.log(obj.name);//undefined 4.调用某个没有返回值的函数,也会返回und

  • Java Swing null绝对布局的实现示例

    1. 概述 官方JavaDocsApi: java.awt.Component,java.awt.Container null,绝对布局.绝对布局没有特定一个布局管理器类来表示,给容器的布局管理器设置为 null,就表示使用绝对布局,即通过设置组件的坐标和宽高来布置组件. 绝对布局需要明确指定每一个组件的坐标和宽高,否则不显示. 对于使用其他布局时给组件设置坐标和宽高,一般会遵循以下两点: 使用其他布局时,如果在窗口显示之后,再添加新组件,则该组件也会被当做绝对布局对待(即需要手动指定坐标和宽高

  • JAVA null详解

    前言 对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java. 我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针.操作符重载.多继承实现的原因,null却与此正好相反.好吧,我真的不知道这个问题的答案,我知道的是不管null

  • java 获取对象中为null的字段实例代码

    下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述: private static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames

  • Java判断对象是否为空(包括null ,"")的方法

    本文实例为大家分享了Java判断对象是否为空的具体代码,供大家参考,具体内容如下 package com.gj5u.publics.util; import java.util.List; /** * 判断对象是否为空 * * @author Rex * */ public class EmptyUtil { /** * 判断对象为空 * * @param obj * 对象名 * @return 是否为空 */ @SuppressWarnings("rawtypes") public

  • Java对象不使用时赋值null的意义详解

    先看代码 public class TestDemo1 { public static void main(String[] args) { if (true) { byte[] placeHolder = new byte[64 * 1024 * 1024]; System.out.println(placeHolder.length / 1024); } System.gc(); } } idea配置gc日志打印 运行上面的代码,载图gc日志 现在我们修改上面的测试代码,将placeHold

  • Java中类赋值的解释实例详解

    Java中类赋值的解释实例详解 Java是面向对象的存储语言,进行的是信息的传递,也就是类的赋值,实际上他们占用的是同样的存储空间: 下面上一个自己写的例子: 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • Java中由substring方法引发的内存泄漏详解

    内存溢出(out of memory ) :通俗的说就是内存不够用了,比如在一个无限循环中不断创建一个大的对象,很快就会引发内存溢出. 内存泄漏(leak of memory) :是指为一个对象分配内存之后,在对象已经不在使用时未及时的释放,导致一直占据内存单元,使实际可用内存减少,就好像内存泄漏了一样. 由substring方法引发的内存泄漏 substring(int beginIndex, int endndex )是String类的一个方法,但是这个方法在JDK6和JDK7中的实现是完全

  • Kotlin null的处理详解

    Kotlin null的处理详解 NullPointerException,俗称NPE,不管菜鸟还是老鸟们,都是不可避免,经常遇到的一个异常,解释起来很简单,就"空指针"三个字.总是在一次不小心,而掉进这个陷阱里.Kotlin 的设计目标就是希望消除代码中 null 引用带来的危险, 也就是所谓的造成十亿美元损失的大错误. NPE的原因 尽管Kotlin希望消除代码中的NPE,我们总是不小心,总会不小心又掉进NPE的陷阱,下面是可能NPE的原因: 明确调用 throw NullPoin

  • Java中的引用和动态代理的实现详解

    我们知道,动态代理(这里指JDK的动态代理)与静态代理的区别在于,其真实的代理类是动态生成的.但具体是怎么生成,生成的代理类包含了哪些内容,以什么形式存在,它为什么一定要以接口为基础? 如果去看动态代理的源代码(java.lang.reflect.Proxy),会发现其原理很简单(真正二进制类文件的生成是在本地方法中完成,源代码中没有),但其中用到了一个缓冲类java.lang.reflect.WeakCache<ClassLoader,Class<?>[],Class<?>

  • 基于Java中最常用的集合类框架之HashMap(详解)

    一.HashMap的概述 HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构. HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作.存储的是对的映射,允许多个null值和一个null键.但此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 除了HashMap是非同步以及允许使用null外,HashMap 类与 Hashtable大致相同. 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性

  • java面向对象设计原则之里氏替换原则示例详解

    目录 概念 实现 拓展 概念 里氏替换原则是任何基类出现的地方,子类一定可以替换它:是建立在基于抽象.多态.继承的基础复用的基石,该原则能够保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余. 实现 里氏替换原则要求我们在编码时使用基类或接口去定义对象变量,使用时可以由具体实现对象进行赋值,实现变化的多样性,完成代码对修改的封闭,扩展的开放.如:商城商品结算中,定义结算接口Istrategy,该接口有三个具体实现类,分别为PromotionalStrategy (满减活动,两

  • Java结构型设计模式之享元模式示例详解

    目录 享元模式 概述 目的 应用场景 优缺点 主要角色 享元模式结构 内部状态和外部状态 享元模式的基本使用 创建抽象享元角色 创建具体享元角色 创建享元工厂 客户端调用 总结 享元模式实现数据库连接池 创建数据库连接池 使用数据库连接池 享元模式 概述 享元模式(Flyweight Pattern)又称为轻量级模式,是对象池的一种实现.属于结构型模式. 类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能.享元模式提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用

  • java 中设计模式(装饰设计模式)的实例详解

    java 中设计模式(装饰设计模式)的实例详解 应用场景: 在不对原有对象类进行修改的基础上,给一个或多个已有的类对象提供增强额外的功能. 我觉得可以从字面理解,装饰,装饰房子.房子可以看成原有的类.等于你把一个已经建好的房子按照自己的想法再装饰一遍.继承也可以实现这样的功能,但是继承有它的缺点,继承只是单一继承.装饰设计模式可以取多个不同的类的不同功能. 具体步骤: ◎第1步:通过构造传参把需要加强的类传过来.(你要装修房子,肯定的先有房子吧.这个很好理解) ◎第2步:把具体需要增强的功能写了

  • Java使用责任链模式处理学生请假问题详解

    本文实例讲述了Java使用责任链模式处理学生请假问题.分享给大家供大家参考,具体如下: 一. 模式定义 在责任链模式中,很多对象由每一个对象对其下家的引用而连接起来,形成一条链.客户端应用请求在这个链上进行传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态地重新组织链和分配责任. (1)抽象处理者角色:定义出一个处理请求的接口.如果需要,接口可以定义出一个方法,以设定和返回下家的引用.这个角色通常由一个Ja

随机推荐