Java垃圾回收

Part 3 垃圾回收

  • 垃圾回收机制只负责回收堆内存中的对象,不包括任何物理资源(数据库连接,网络IO等资源)
  • 程序无法精确主动控制垃圾回收的进行
  • 回收任何对象前,系统总会调用被回收对象的finalize()方法,该方法可能使得对象重新复活
3.1 垃圾回收机制

对象在内存中的三种状态:
可达状态——有变量引用;
可恢复状态——无变量引用;
不可达状态——无变量引用,且系统调用finalize()方法后仍然不能让对象变成可达状态。只有这种状态的对象会被回收。

强制垃圾回收:

System.gc();
或
Runtime.getRuntime().gc();

上述方法,虚拟机会尽最大努力实现,并不百分百可靠。
tip:java -verbose:gc 类名
该指令能看到每次垃圾回收后的提示信息

finalize()方法:

  • 不要主动调用对象的该方法;
  • finalize方法何时被调用具备一定的不确定性;
  • 系统执行可恢复对象的finalize()方法时,可能会把系统中的对象或者其他对象重新变成可达状态;
  • JVM执行finalize出现异常时,垃圾回收机制不会报告异常,继续执行。

强制调用finalize():

Runtime.getRuntime().runFinalization();
System.runFinalization();

和强制GC一样,虚拟机会尽最大努力实现,并不百分百可靠。如果要确保资源回收,建议使用try finally

一般来说强制垃圾回收时需要调用如下组合:

System.gc();
System.runFinalization();
3.2对象的软、弱和虚引用
  • 强引用 常见的引用方式,当一个对象被至少一个变量强引用时,就处于可达状态。系统不能回收有强引用的对象。
  • 软引用 当对象只有软引用时,当垃圾回收机制运行,就可能会被垃圾回收,这取决于内存是否紧张。
  • 弱引用 当对象只有弱引用时,当垃圾回收机制运行,无论系统内存是否足够,它都会被回收。
  • 虚引用 近似于无引用,主要用于跟踪对象被垃圾回收的状态。只有虚引用的对象,任何时候都可能被回收。虚引用不能单独使用,必须和ReferenceQueue一起使用。
    上述引用都包含了一个get()方法,用于获取被他们引用的对象。

*tips:
1.程序可以检查与虚引用关联的引用队列中是否包含了该虚引用,从而了解该虚引用所指的对象是否即将被回收;

2.tip:如果要测试引用,创建字符串对象时,要用String str = new String("测试字符串"), 不能使用 String str = " 测试字符串"; 后者会被系统直接使用常量池来管理这个字符串直接量(也是强引用),但不会被垃圾回收机制回收。

3.如果要使用特殊引用类的特性,就不要保留对象的强引用。*

你可能感兴趣的:(Java垃圾回收)