垃圾收集 Garbage Collection 通常被称为GC,即Java垃圾回收机制。
四种引用类型
- 强引用(StrongReference)
Java中默认声明的就是强引用,:只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError
- 软引用(SoftReference):
在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,实现缓存技术,比如网页缓存,图片缓存等。
- 弱引用(SoftReference):
无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。
- 虚引用(PhantomReference):
通过一个虚引用申明。那么它就和没有任何引用一样,它随时可能会被回收仅用来处理资源的清理问题,比Object里面的finalize机制更灵活。get方法返回的永远是null,Java虚拟机不负责清理虚引用,但是它会把虚引用放到引用队列里面。
引用队列
引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾s回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。
一、GC是做什么的
在程序运行时,内存空间是有限的,那么如何及时的把不在使用的对象清除,将内存释放出来,这就是GC要做的事。
理解GC机制就要从“GC的区域在哪里”“GC回收的对象是什么”“什么时候出发GC”“GC做了什么事”
1.1 需要GC的内存区域
jvm中,程序计数器、虚拟机栈、本地方法栈都是随着线程而生随着线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于Java堆和方法区中,在程序运行期间,这部的内存的分配和使用都是动态的
1.2 GC回收的对象是什么
需要进行回收的对象就是不在存活的对象,那么如何判断一个对象是否存活的,有两种常用方法:引用计数法和可达性分析法。
- 引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,计数为0时可以回收。但是此方法无法解决对象相互循环引用的问题
- 可达性分析法(Reachability Analysis):从GC Roots开始向下搜索,搜索走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连时,证明此对象是不可用的,不可达对象。
在Java语言中,GCRoots包括:虚拟机栈中引用的对象,方法区中类静态属性实体引用的对象。方法区中常量引用的对象。本地方法栈中JNI引用的对象。
生存还是死亡?
都要经历两次标记过程:1.是否有GCroot引用链 2.是否执行finalize()方法释放空间
(1)对象没有覆盖finalize()方法
(2)finalize()方法已经被虚拟机执行过了
这两种情况都判定为不用执行finalize()方法。