GC详解

GC 的作用域

 

JVM-GC垃圾回收

口诀:关于垃圾回收:分代收集算法 ==不同的区域使用不同的算法==

Young代: GC频繁区域

Old代:GC次数较少

Perm代:不会产生GC!

 

一个对象的历程!

 

JVM-GC垃圾回收

JVM在进行GC时,并非每次都是对三个区域进行扫描的!大部分的时候都是指的新生代!

两个类型:

普通GC:只针对新生代 【GC】

全局GC:主要是针对老年代,偶尔伴随新生代! 【Full GC】

GC四大算法

引用计数法

 

JVM-GC垃圾回收 

特点:每个对象都有一个引用计数器,每当对象被引用一次,计数器就+1,如果引用失效,则计数器-1,如果为0,则GC可以清理;

缺点:

  • 计数器维护麻烦!

  • 循环引用无法处理!

JVM 一般不采用这种方式

现在一般使用可达性算法,GC Root...

 

==复制算法==

JVM-GC垃圾回收

年轻代中,就是使用的复制算法!

 

1、一般普通GC 之后,差不多Eden几乎都是空的了!

2、每次存活的对象,都会被从 from 区和 Eden区等复制到 to区,from 和 to 会发生一次交换;记住一个点就好,谁空谁是to,每当幸存一次,就会导致这个对象的年龄+1;如果这个年龄值大于15(默认值,后面我们会讲解调整),就会进入养老区!

JVM-GC垃圾回收 

 

优点:没有标记和清除的过程!效率高!没有内存碎片!

缺点:==需要浪费双倍的空间==

Eden 区,对象存活率极低! 统计:99% 对象都会在使用一次之后,引用失效!推荐使用 ==复制算法==

 

标记清除算法

JVM-GC垃圾回收 

老年代一般使用这个,但是会和我们后面的整理压缩一起使用!

 

优点:不需要额外的空间!

缺点:两次扫描,耗时较为严重,会产生内存碎片,不连续!

 

标记清除压缩!

 

JVM-GC垃圾回收

减少了上面标记清除的缺点:没有内存碎片!但是耗时可能也较为严重!

那我们什么时候可以考虑使用这个算法呢?

在我们这个要使用算法的空间中,假设这个空间中很少,不经常发生GC,那么可以考虑使用这个算法!

 

小总结

内存效率:复制算法 > 标记清除算法 > 标记整理(时间复杂度!)

内存整齐度:复制算法=标记整理>标记清除算法

内存利用率:标记整理 = 标记清除算法 > 复制算法

从效率来说,复制算法最好,但是空间浪费较多!为了兼顾所有指标,标记整理会平滑一点,但是效率不尽人意!

难道就没有一种最优的算法吗?思考一下:

答案:没有!没有最好的,只有最合适的!=> 分代收集算法:不同的区域使用不同的算法!

年轻代:

相对于老年区,对象存活率低!

Eden 区,对象存活率极低! 统计:99% 对象都会在使用一次之后,引用失效!推荐使用 复制算法

老年代:

区域比较大,对象存活率较高!

推荐使用:标记清除压缩!

 

JVM 垃圾回收的时候如何确定垃圾,GC Roots?

什么是垃圾:简单地说,就是不在被引用的对象!

Person person = null;

如果我们要进行垃圾回收,第一步:判断这个对象是否可以回收!

引用计数法!(上面已经谈过)

Java中,引用和对象都是有关联的,如果要操作对象,就要通过引用进行;

可达性分析算法!

JVM-GC垃圾回收 

 

一切都是从 GC Root 这个对象开始遍历的,只要在这里面的就不是垃圾!

 

什么是Gc Root,(4种)

1、虚拟机栈中引用的对象!

2、类中静态属性引用的对象

3、方法区中的常量

4、本地方法栈中 Native 方法引用的对象!

相关文章:

  • 2021-09-16
  • 2022-01-18
  • 2021-09-14
  • 2021-08-29
  • 2021-05-16
  • 2021-10-10
  • 2021-11-17
  • 2021-11-25
猜你喜欢
  • 2021-10-22
  • 2022-01-10
  • 2021-07-20
  • 2022-01-08
  • 2021-07-08
  • 2021-10-25
  • 2021-09-16
相关资源
相似解决方案