JVM系列文章
- 深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器_eden used total max-CSDN博客
- JVM深入原理(一+二):JVM概述和JVM功能-CSDN博客
- JVM深入原理(三+四):JVM组成和JVM字节码文件-CSDN博客
- JVM深入原理(五):JVM组成和JVM字节码文件-CSDN博客
- JVM深入原理(六)(一):JVM类加载器-CSDN博客
- JVM深入原理(六)(二):双亲委派机制-CSDN博客
- JVM深入原理(七)(一):运行时数据区-CSDN博客
- JVM深入原理(七)(二):运行时数据区-CSDN博客
- JVM深入原理(八)(一):垃圾回收-CSDN博客
- JVM深入原理(八)(二):垃圾回收-CSDN博客
目录
8. JVM垃圾回收
8.1. 垃圾回收-作用
- 垃圾回收的作用:Java中为了简化对象的释放,引入了自动垃圾回收(Garbage Collection简称GC)机制,通过GC来对堆上不再被引用的对象完成自动回收
8.2. 垃圾回收-方法区回收
- 方法区中保存了类的元信息,能回收的内容主要也是不再使用的类
- 如何判定一个类是否可以被卸载回收呢?同时满足下面三个条件
- 此类的所有实例对象均已被回收,堆中不存在任何该类的对象或子对象
- 加载该类的类加载器已被回收
- 该类对应的字节码对象没有在任何地方被引用
8.3. 垃圾回收-手动触发垃圾回收
调用System.gc():调用此方法不一定会触发垃圾回收,只是给JVM发出一个请求,具体执行JVM自行判断
8.4. 垃圾回收-堆回收
8.4.1. 回收判断-引用计数法
引用计数法-原理:每当对象被另外一个对象引用时计数+1,当对象的引用计数为0时,则说明当前对象无人引用可以被回收.
引用计数法-缺点:如果两个对象循环引用,而又没有其他的对象来引用它们,这样就造成垃圾堆积
编辑
8.4.2. 回收判断-可达性分析算法
可达性算法-原理(JVM采用):JVM先确定根对象(GC Roots),再扫描堆中的对象是否直接或间接的被根对象引用,如果没被引用,则可以垃圾回收,反之不收.
GC Roots一般是System Class,Native Stack,Thread,Busy Monitor
8.5. 垃圾回收-五种引用
8.5.1. 强引用
强引用-作用:可达性算法描述的根对象引用普通对象的引用,指的就是强引用,只要有这层关系存在,被引用的对象就会不被垃圾回收
8.5.2. 软引用
软引用-作用:JVM中使用SoftReference对象来实现软引用,一般在缓存中使用,当程序内存不足时,被引用的对象就会被回收.
SoftReference对象也需要被根对象引用,否则其自身就会被回收
编辑
引用队列-作用:存放内容为空的软引用对象,可以遍历引用队列将软引用对象释放
引用队列-软引用对象运行流程:
- 软引用对象创建时,通过构造器传入引用队列
- 当软引用对象引用的对象均被回收后,该软引用对象会被放入引用队列中
- 通过遍历引用队列可将软引用对象的强引用删除,然后垃圾回收
8.5.3. 弱引用
弱引用-作用:JVM中使用WeakReference对象来实现软引用,一般在ThreadLocal中,当进行垃圾回收时,被弱引用对象引用的对象就直接被回收.
WeakReference对象也需要被根对象引用,否则其自身就会被回收
WeakReference对象也可以被引用队列回收
8.5.4. 虚引用
虚引用-作用:当对象被垃圾回收时可以接收到对应的通知,但是不能通过虚引用对象获取引用的对象.Java中使用PhantomReference实现了虚引I用,直接内存中为了及时知道直接内存对象不再使用,从而回收内存,使用了虚引用来实现。
8.5.5. 终结器引用
终结器引用-作用:在对象需要被回收时,对象会被放置在Finalizer类中的引用队列中并在稍后由一条由FinalizerThread线程从队列中获取对象,然后执行对象的finalize方法。在这个过程中可以在finalize方法中再将自身对象使用强引用关联上,但是不建议这样做,如果耗时过长会影响其他对象的回收。