JVM虚拟机三之GC垃圾回收

JVM虚拟机 GC垃圾回收

垃圾回收主要做三件事:哪些内存需要回收,什么时候回收,怎么回收。

垃圾回收主要的知识点:判断对象是否存活,垃圾收集算法,各类垃圾收集器以及垃圾回收过程。

Java对象之死

1.引用计数法,JVM没有用。但是每个教程都会告诉你。是不是因为《深入理解Java虚拟机》太过经典,里边介绍了这用引用计数法,所以往后的教程都需要这个啊。

我就记一句话:不能解决互相引用,循环引用。

2.可达性分析

通过一些GC Roots对象作为起点,然后一路标记引用对象,存放到存活引用集合中。没有被标记的对象就作为被回收的对象了。

GC Roots对象的分类:

  • 全局性引用,方法区的静态对象,常量对象的引用
  • 执行上下文,对Java方法栈帧中的局部变量的对象引用,对JNI handles对象引用
  • 已启动且未停止的Java线程

存在的问题:

  • 误报:已经可以回收的对象,被标记为存活,垃圾回收不到,可能性较小,占用一会内存,影响不大。
  • 楼板:正在引用的对象没有被标记存活,被垃圾回收,直接导致JVM崩溃。 - 通过垃圾回收时,STW确保可达性分析的准确性,避免漏报。

垃圾回收算法

  1. 标记-清除算法
  • 标记无引用的死亡对象所占据的空闲内存,记录到空闲列表(free list)。
  • 创建对象的时候,从free list表中找到空闲内存,分配给新的对象。
  • 这个算法简单高效,但是会产生很对的内存碎片。
  • JVM堆中的对象,必须是连续分布的,所以极端的情况下可能会剩余内存足,但是找不到符合要求大小的连续的内存,导致无法分配对象。
  • 在CMS垃圾回收器,使用了这种算法,GC暂停时间短,但存在算法缺陷。
  1. 标记-复制算法
  • 将内存空间分为两份,通过from和to两个指针维护,from指针指向的内存区域分配分配内存
  • 垃圾回收时,将存活对象复制到to指针指向的内存区域,并交换from指针和to指针。
  • 解决内存碎片的问题,但是造成内存空间的浪费,只有一半用来存储对象。
  1. 标记 - 压缩算法
  • 标记阶段与标记-清除算法一样,在清理的过程中,先将存活的对象向内存一边移动整理,然后再清理其他的空间。
  • 这种算法解决了标记-清除算法中产生的内存碎片问题,但是压缩算法增加了开销。

垃圾收集器

  1. 新生代
  • Serial(连续的)

采用标记-清除算法,简单高效的单核机器,Clinet模式下默认新生代收集器。

  • Parallel ParNew

采用标记-复制算法,GC线程并行版本,在单CPU下效果不明显,常用于Client模式下的JVM。

  • Parallel Scavenge

标记-复制算法,目标是达到可控制吞吐量(吞吐量 = 用户代码运行时间/(用户代码运行时间+垃圾回收时间))

  1. 老年代
  • Serial Old

标记-压缩算方法;性能一般,单线程版本。1.5版本之前,与Parallel Scavenge配合使用;作为CMS的后备预案。

  • Parallel Old

采用标记压缩算法;GC多线程并行,替代了Serial Old与Parallel Scavenge配合使用。

  • CMS

标记-清除算法;对CPU资源敏感,停顿时间长;会产生碎片,通过参数开启碎片的合并整理。

  1. g1

采用标记-压缩算法;适用于大内存机器,GC多线程并行执行,低停顿,高回收效率。

总结

大体的记录了JVM垃圾回收的内容,垃圾对象的判断,垃圾回收算法,垃圾收集器。

posted @   搬砖的孟达  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
点击右上角即可分享
微信分享提示