写点什么

架构师训练营第 9 周作业

用户头像
netspecial
关注
发布于: 2020 年 11 月 22 日



请简述 JVM 垃圾回收原理。

JVM 垃圾回收就是将JVM 堆中的已经不再被使用的对象清理掉,释放堆空间。

  • 一,需要知道哪些对象不再被使用

JVM 通过一种可达性分析算法进行垃圾对象的识别,具体过程是:从线程栈帧中的局部变量,或者是方法区的静态变量出发,将这些变量引用的对象进行标记,然后看这些被标记的对象是否引用了其他对象,继续进行标记,所有被标记过的对象都是被使用的对象,而那些没有被标记的对象就是可回收的垃圾对象了。

  • 二,进行完标记以后,JVM 就会对垃圾对象占用的内存进行回收,回收主要有三种方法:

  • 清理:将垃圾对象占据的内存清理掉,其实JVM 并不会真的将这些垃圾内存进行清理,而是将这些垃圾对象占用的内存空间标记为空闲,记录在一个空闲列表里,当应用程序需要创建新对象的时候,就从空闲列表中找一段空闲内存分配给这个新对象。

  • 压缩:从堆空间的头部开始,将存活的对象拷贝放在一段连续的内存空间中,那么其余的空间就是连续的空闲空间。

  • 复制:将堆空间分成两部分,只在其中一部分创建对象,当这个部分空间用完的时候,将标记过的可用对象复制到另一个空间中。

  • 为什么这么麻烦而不是直接清理呢?

  • 为了避免生成碎片空间,生成连续空间以供例如数组使用。

  • 三,具体回收的时候,JVM还是用一种分代垃圾回收的策略

  • 把内存分为两个代,一个叫新生代,一个叫做老年代

  • 实际过程中,大部分Java的对象生存时间很短。把这些对象放到一个较小的区域中去,回收速度更快。对象创建的时候在新生代中创建,回收的时候先在新生代中回收。如果经过了一段时间,对象还没有被回收掉,说明这个对象的生命周期比较长,然后再把它复制到老年代。

  • 新生代中分了三个区,Eden区,From区和To区。新对象在Eden区中创建,当Eden区满的时候,开始进行垃圾回收,用复制算法,在用的对象复制到From区。当From区满了,把对象复制到To区。复制了几次后,还有对象没有被回收,则把这些对象复制到老年代。一段时间后,如果老年代也满了,会对老年代进行垃圾回收。存在两种垃圾回收过程,一种是Young GC(新生代垃圾回收),一种是Full GC(新生代和老年代一起垃圾回收)。

  • 四,JVM 垃圾回收器算法

  • 串行回收器 - 应用程序多线程的执行,当需要进行垃圾回收的时候,所有的线程都停止运行,启动一个垃圾回收线程,进行对象的标记,标记完了以后,进行垃圾空间的清理回收。垃圾回收完了以后,再启动应用程序线程,多线程并发执行。垃圾回收线程只有一个。

  • 并行回收器 - 多CPU核心时代,针对CPU的核心数,启动多个垃圾回收线程,并行的进行垃圾回收。并行垃圾回收的时候,仍然终止所有的用户线程。

  • 并发垃圾回收器CMS - 把整个垃圾回收过程分得更加详细,把整个过程分成四个阶段:

  • 初始化标记 - 依然终止所有用户线程

  • 并发标记 - 垃圾回收线程和用户线程是并发执行的

  • 重标记 - 因为有新对象产生,所以要重新标记。仍然终止所有用户线程

  • 并发清理 - 清理的垃圾回收线程和用户线程并发执行。

  • G1 垃圾回收器 - 把内存空间分成了更小的区域,默认情况下分成2000个区域,每个区域管理较小的内存空间,越小越快。动态的调整回收的过程,对用户程序影响比较小,占用的资源也比较小。

  • Eden

  • Survivor

  • Old

  • Humongous



用户头像

netspecial

关注

还未添加个人签名 2011.07.20 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第 9 周作业