【JVM】垃圾回收

【JVM】垃圾回收,第1张

文章目录
  • 前言
    • 四种引用类型
      • 强引用
      • 软引用
      • 弱引用
      • 虚引用
    • 垃圾回收算法
      • 1. 标记-清除算法
      • 2. 复制算法
      • 3. 标记-整理算法
      • 4. 分代算法
    • 收集器


前言

提到JVM就肯定要提垃圾回收,内存的自动管理,是很多高级语言的一大特性,对于不同的应用,组合不同的回收算法,不单是体现对JVM的理解,也是非常有趣的过程


四种引用类型

对于Java的引用类型还是有必要了解的,因为不同的类型会影响到回收的策略


强引用

这是Java中最常见的引用类型,一个对象赋值给一个变量,这个引用变量就是一个强引用
当一个对象被强引用变量引用时,即处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远不会用到JVM也不会回收。所以这也是造成Java内存泄漏的主要原因之一

软引用

软引用是通过继承SoftReference类来实现的,用来描述一些有用但并非必须的对象。对于这类对象来说,当内存足够时,它是安全的。但如果系统内存空间不足时,它就会被回收

弱引用

软引用是通过继承WeakReference类来实现的,它的生命周期较软引用更短,只要垃圾回收机制一运行,不管JVM的内存空间是否充足,它都会被回收

虚引用

也称为幽灵引用或者幻影引用(听着挺屌),然而是最弱的一种引用关系
是通过继承PhantomReference类来实现的,不能单独使用,必须和引用队列联合使用,主要的作用就是跟踪对象被垃圾回收的状态


垃圾回收算法

对引用类型咱们心里有数了,下面咱们看看都有哪些垃圾回收的算法:

1. 标记-清除算法

这个也是最基础的收集算法了,后续的收集算法发展,基本都是由它演变、优化而来的
如同名字一样,分为两个阶段:先标记,再清除,先找到需要回收的对象进行标记,然后统一回收

缺点:

  1. 效率不高,两个阶段的效率都一般
  2. 标记后,会产生很多不连续的内存碎片,导致后续分配大对象时,无法分配进而触发再次回收
2. 复制算法

方式是将内存分为大小相等的两块,每次只使用其中的一块,当一块内存用完了,就将还存活着的对象复制到另外一块上面,然后再把之前的内存空间一次清理掉,现在的商业虚拟机基本都用这种来处理新生代

IBM公司专门研究表明了新生代的对象98%都是朝生夕死的,所以就演变出了之前提到的Eden和From Survivor和To Survivor空间,而默认的8:1:1这样的黄金比例,也应该是通过大量的实践数据得来的最优解

3. 标记-整理算法

与标记-清除类似,只不过并不是直接对可回收对象进行清理,而是让所有存活的对象都向一断移动,然后直接清理掉端边界意外的内存

4. 分代算法

当前商业虚拟机的垃圾收集采集基本都采用了这种算法,改变了以往的分区逻辑,改为分代逻辑
即根据对象存活周期的不同将内存划分为几块
一般是把Java堆分为新生代和老年代,然后根据各个年代的特点采取适当的收集算法


收集器

上边就是方法论,收集器就是具体实现了

  1. Serial:最基础的垃圾收集器,是单线程+复制算法
  2. ParNew:它其实就是Serial的多线程版本
  3. Parallel Scavenge:同样是多线程+复制算法,区别是它重点关注的是程序达到一个可控制的吞吐量
  4. Serial Old:它用的是单线程+标记-整理算法,主要是Client端默认的JVM老年代垃圾收集器
  5. Parallel Old:从名字也可以看出来它是Parallel Scavenge的老年代版本,使用的是多线程+标记-整理算法
  6. CMS:使用的是多线程+标记-清除算法
  7. G1:当下最流行的收集器,横跨新老两代,基于并行+标记-整理算法

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/799855.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存