Java 对象与垃圾回收

程序创建对象、数组等引用类型实体时,系统都会在堆内存为之分配一块内存区,对象就保存在这些内存区中,当这块内存不再被任何引用变量引用的时候,这块内存就变成垃圾,等待垃圾回收机制来回收。

垃圾回收机制有如下特点:
在这里插入图片描述
本文包含如下内容:

  1. 对象在内存中的状态
  2. 强制垃圾回收
  3. finalize方法
  4. 对象的软、弱和虚引用

1. 对象在内存中的状态

对象在堆内存中运行时,根据其被引用变量引用的状态,可将其所处的状态分为如下三种:
在这里插入图片描述
以下是三种状态转换示意图:
在这里插入图片描述
下面程序简单地创建了两个字符串对象,并创建一个引用变量依次指向两个对象。
在这里插入图片描述
在这里插入图片描述

2. 强制垃圾回收

程序只能控制一个对象何时不再被任何引用变量引用,绝不能控制它何时被回收。
强制垃圾回收:
在这里插入图片描述
下面程序创建了4个匿名对象,每个对象创建之后立即进入可恢复状态,等待系统回收,但直到程序退出,系统依然不会回收该资源。
在这里插入图片描述
编译运行上面的程序,直到系统退出,系统都不曾调用GcTest对象的 finalize()方法,如果将程序修改如下:
在这里插入图片描述
这个代码增加了强制回收语句,垃圾回收机制会在收到该语句之后“有所动作”

3.finalize方法

在这里插入图片描述
任何Java 类都可以重写 Object 类的 finalize() 方法,在该方法中清理该对象占用的资源。
在这里插入图片描述
finalize()方法具有如下四个特点:
在这里插入图片描述
下面程序演示了如何在 finalize() 方法里复活自身,并可通过该程序看出垃圾回收机制的不确定性:
在这里插入图片描述
在这里插入图片描述
上面程序定义了一个FinalizeTest 类,重写了该类的 finalize()方法,在该方法中把需要清理的可恢复对象重新赋给了 ft 引用变量,从而让该可恢复对象重新变成可达状态。

mian方法中创建了一个FinalizeTest 类的匿名对象,因为创建后没有把这个对象赋给任何引用变量,所以该对象立即进入可恢复状态。

进入可恢复状态后,系统调用1号粗体字代码通知系统进行垃圾回收,2号粗体字代码强制系统立即调用可恢复对象的 finalize() 方法,再次调用 ft 对象的 info() 方法。编译运行上面程序,看到 ft 的 info()方法被正常执行。

如果删除 1 行代码,取消强制垃圾回收,再次编译运行上面程序,则会出现异常。
在这里插入图片描述
即取消 1 行粗体字代码后,程序并没有通知系统开始执行垃圾回收(而且程序内存也没有紧张),因此系统通常不会立即进行垃圾回收,也就不会调用 FinalizeTest 对象的 finalize()方法,这样 FinalizeTest 的 ft 类变量依然保持为 null ,就会出现空指针异常。
在这里插入图片描述

4. 对象的软、弱和虚引用

java.lang.ref 包下提供了 3 个类:SoftReference、PhantomReferer 和 WeakReference。分别代表系统对对象的 3 种引用方式:软引用、虚引用和弱引用。

Java语言对对象的引用有如下四种方式:

1. 强引用
在这里插入图片描述
2. 软引用
在这里插入图片描述
3. 弱引用
在这里插入图片描述
4. 虚引用
在这里插入图片描述
上面三个引用类都包含了一个 get() 方法,用于获取被它们引用的对象。
在这里插入图片描述
软引用和弱引用可以单独使用,但虚引用不能单独使用,虚引用的主要作用是跟踪对象被垃圾回收的状态。

下面程序示范了弱引用所引用的对象被系统垃圾回收的过程:
在这里插入图片描述
在这里插入图片描述
编译上面程序会出现警告提示,这个警告提示是一个泛型提示。此处先不要理它。不仅如此,创建字符串对象时,不要使用 String str = "疯狂JAVA讲义";否则看不到运行效果。因为在这种情况下,系统会使用常量池来管理这个字符串直接量(会使用强引用来引用它),系统不会回收这个字符串直接量。
在这里插入图片描述
下面程序使用了虚引用来引用字符串对象,虚引用无法获取它引用的对象。下面程序还将虚引用与引用队列结合,虚引用所引用的对象被垃圾回收后,虚引用将被添加到引用队列中。
在这里插入图片描述
程序的输出分析:
在这里插入图片描述
使用这些引用类的好处:
在这里插入图片描述
注意事项:
使用这些特殊的引用类,就不能保留对对象的强引用
保留了对对象的强引用,就会浪费这些引用类提供的好处。

由于垃圾回收机制的不确定性,当程序希望从软、弱引用中取出被引用对象时,可能这个被引用对象已经完全释放了。如果程序需要使用那个被引用的对象,则必须重新创建该对象。这个方法可以通过两种方式完成。

取出弱引用所引用的对象
方法1:
在这里插入图片描述在这里插入图片描述
方法2:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值