Java中各种引用(Reference)解析
目录
类型 对应类 特征 强引用 强引用的对象绝对不会被gc回收 软引用 SoftReference 如果物理内存充足则不会被gc回收,如果物理内存不充足则会被gc回收。 弱引用 WeakReference 一旦被gc扫描到则会被回收 虚引用 PhantomReference 不会影响对象的生命周期,形同于无,任何时候都可能被gc回收 FinalReference 用于收尾机制(finalization) 2, FinalReference
FinalReference
访问权限为package,并且只有一个子类Finalizer
,同时Finalizer
是final修饰的类,所以无法继承扩展。 与
Finalizer
相关联的则是Object中的finalize()
方法,在类加载的过程中,如果当前类有覆写finalize()
方法,则其对象会被标记为finalizer类,这种类型的对象被回收前会先调用其finalize()
。 具体的实现机制是,在gc进行可达性分析的时候,如果当前对象是finalizer类型的对象,并且本身不可达(与GC Roots无相连接的引用),则会被加入到一个
ReferenceQueue
类型的队列(F-Queue)中。而系统在初始化的过程中,会启动一个FinalizerThread
实例的守护线程(线程名Finalizer),该线程会不断消费F-Queue中的对象,并执行其finalize()
方法(runFinalizer),并且runFinalizer方法会捕获Throwable级别的异常,也就是说finalize()
方法的异常不会导致FinalizerThread
运行中断退出。对象在执行finalize()
方法后,只是断开了与Finalizer
的关联,并不意味着会立即被回收,还是要等待下一次GC,而每个对象的finalize()
方法都只会执行一次,不会重复执行。
finalize()
方法是对象逃脱死亡命运的最后一次机会,如果在该方法中将对象本身(this关键字) 赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移出"即将回收的集合"。——《深入理解java虚拟机》
注意:finalize()使用不当会导致内存泄漏和内存溢出,比如
SocksSocketImpl
之类的服务会在finalize()
中加入close()
操作用于释放资源,但是如果