JVM垃圾回收
作者:互联网
1 如何判断对象可以回收
1.1引用计数法
通过统计这个对象被引用的数量,来判断是否可以被回收,但是当两个对象互相引用的时候,就判断不出这个对象是可以被回收的了, JVM虚拟机并没有使用这个回收方法
1.2 可达性分析算法(JVM使用)
如果一个对象被根对象直接或间件的引用,则这个对象不能被回收。否则则相反。
- Java虚拟机中的垃圾回收采用可达性分析来探索所有存活的对象
- 扫描堆中的对象,看是否能够沿着GC Root对象做为引用链找到该对象,找不到,表示可以回收
1.3 四种引用
- 强引用 : 一般情况下,直接赋值的对象,就是强引用
- 软引用: GCRoot引用软引用, 然
- 弱引用: GCRoot引用弱引用, 然后弱引用 对象,当发生垃圾回收时,不管内存够不够,都会被回收
- 虚引用: 当虚引用引用的对象被垃圾回收时,虚引用对象就会被放入引用队列,然后有东西会扫描引用队列,然后释放虚引用所对应的那块直接内存
- 终结器引用: 当对象重新了finallize(),就会有终结器引用这点对象,当没有强引用的时候, 终结器引用就会被放入引用队列,
软引用和弱应用还可以配合引用队列使用()
虚引用和终结器引用必须配合引用队列使用
2.垃圾回收算法
2.1 标记清除
先对无引用的对象进行标记,然后再一起清除
优点: 速度快
缺点: 容易造成内存碎片
2.2标记整理
优点: 对内存碎片进行了整理, 确定: 因为对碎片进行了整理,所以更耗时了
2.3 标记复制算法
- 先标记,不被引用的对象,
- 把引用的对象,复制到新的一块内存中,
- 把原内存中的对象全部清空,
- 交换两块内存位置,让新内存变旧内存,旧内存变新内存
优点:不会产生碎片,缺点: 会占用双倍的内存空间
JVM 是通过协同三种算法来实现的
JVM 的GC回收是通过分代回收的方式来实现回收的,
1. 分为两大块 : 新生代和老年代。新生代又分为:伊甸园 ,幸存区From, 幸存区To
- 当new的对象都会放入伊甸园中, 当伊甸园的空间不够时, 新生代会进行一次垃圾回收,也就是Minor GC。minor gc会引发stop the world, 暂停其他用户的线程,等待垃圾回收结束,用户线程才恢复运行。
- 会进行一次标记复制算法, 把伊 甸园中 幸存的对象放入幸存区To中,并且存活下来的对象寿命加一。
- 然后幸存区To会与幸存区From进行交换, 当然数据实际的地址并不会改变, 而是交换指针来实现交换
- 当回收多次后,幸存区对象的寿命超过了一个阈值,这个超过阈值 的对象就会被放入到老年代中,最大寿命是15(4bit)。有时当新生代内存不足时,也会提前放入老年代中。
- 当老年代中内存满了并且新生代Minor GC后也放不下新对象时, 就会产生一次 Full GC。STW的时间更长
2 参数
4. 垃圾回收器
1.串行
- 单线程
- 堆内存较小,适合个人电脑
2.吞吐量优先
- 多线程
- 堆内存较大,多核cpu
- 尽可能让STW的时间最短
3.响应时间优先 (CMS)
- 多线程
- 堆内存较大,多核cpu
- 尽可能让单次STW的时间最短
4.G1
定义: Garbage First
- 2014 JDK9 默认
适用场景 - 同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是200ms
- 超大堆内存,会将堆划分为多个大小相同的Region
- 整体上是标记+整理算法,两个区域之间是复制算法
标签:对象,引用,回收,幸存,内存,JVM,垃圾 来源: https://blog.csdn.net/qq_23079469/article/details/118760976