对象的不同的可达性状态和对垃圾收集

本文探讨了Java中对象的可达性状态,包括强可达、软可达、弱可达和幻象可达,以及它们对垃圾收集的影响。垃圾收集器通过标记-清除算法回收不再可达的对象。同时,文章介绍了引用类型,如SoftReference、WeakReference和PhantomReference,以及Finalizers在对象生命周期中的角色。Java的垃圾收集机制避免了手动内存管理,但Finalizers不是可靠的资源清理方式。
摘要由CSDN通过智能技术生成

我们说的不同的引用类型其实都是逻辑上的,而对于虚拟机来说,主要体现的是对象的不同的可达性(reachable) 状态和对垃圾收集(garbage collector)的影响。

初识引用

对于刚接触 Java 的 C++ 程序员而言,理解栈和堆的关系可能很不习惯。在 C++ 中,可以使用 new 操作符在堆上创建对象,或者使用自动分配在栈上创建对象。下面的 C++ 语句是合法的,但是 Java 编译器却拒绝这么写代码,会出现 syntax error 编译错误。

Integer foo = Integer(1);

Java 和 C 不一样,Java 中会把对象都放在堆上,需要 new 操作符来创建对象。本地变量存储在栈中,它们持有一个指向堆中对象的引用(指针)。下面是一个 Java 方法,该方法具有一个 Integer 变量,该变量从 String 解析值

public static void foo(String bar){
    Integer baz = new Integer(bar);
}

这段代码我们使用堆栈分配图可以看一下它们的关系

小心点,别被当成垃圾回收了。

 

首先先来看一下 foo() 方法,这一行代码分配了一个新的 Integer 对象,JVM 尝试在堆空间中开辟一块内存空间。如果允许分配的话,就会调用 Integer 的构造方法把 String 字符串转换为 Integer 对象。JVM 将指向该对象的指针存储在变量 baz 中。

上面这种情况是我们乐意看到的情况,毕竟我们不想在编写代码的时候遇到阻碍,但是这种情况是不可能出现的,当堆空间无法为 bar 和 baz 开辟内存空间时,就会出现 OutOfMemoryError,然后就会调用垃圾收集器(garbage collector) 来尝试腾出内存空间。这中间涉及到一个问题,垃圾收集器会回收哪些对象?

垃圾收集器

Java 给你提供了一个 new 操作符来为堆中的对象开辟内存空间,但它没有提供 delete 操作符来释放对象空间。当 foo() 方法返回时,如果变量 baz 超过最大内存,但它所指向的对象仍然还在堆中。如果没有垃圾回收器的话,那么程序就会抛出 OutOfMemoryError 错误。然而 Java 不会,它会提供垃圾收集器来释放不再引用的对象。

当程序尝试创

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值