第 9 周命题作业

用户头像
hifly
关注
发布于: 2020 年 07 月 31 日
第9周命题作业

请简述 JVM 垃圾回收原理



JVM 主要由类加载器,运行时数据区,执行引擎三部分组成。



其中运行时数据区包括:方法区,java栈,堆,程序计数寄存器四个部分。

方法区:主要存放从磁盘加载进来的类字节码。

堆:存放程序运行过程中创建的类实例。

方法区和堆是所有线程共享的。



java栈:存放方法运行期的局部变量

程序计数寄存器:存放当前线程执行到哪一行字节码指令。

java栈和程序计数寄存器是每个线程独享的。



JVM 垃圾回收回收的是堆中不用的对象。那么怎么知道哪些对象是不用的呢?JVM通过一种叫做可达性分析的算法进行识别。什么是可达性分析的算法呢?简单来说就是对象进行逐层标记,如果没有被标记到的对象就认为没有被引用,可以进行删除。那么从哪里开始进行逐层标记呢?JVM选择从java栈 栈帧的局部变量或者方法区的静态变量出发,先将这些变量引用的对象进行标记,然后看这些被标记的对象是否引用了其他对象,继续进行标记。就这样一级一级的进行查找标记,直到所有被引用的对象都被标记了,哪些剩下的没有被标记的对象就是可回收的垃圾对象了。



标记完成之后,JVM就会对没有任何引用的对象进行回收了。回收的算法主要由三种方式组成:清理,压缩和复制。



清理:并不真正进行清理,而是将没有引用的对象占用的内存空间标记为空闲,记录在一个空闲列表中。当需要创建一个新对象时,就从空闲列表中找一段空闲内存分配给这个对象。

压缩:从堆空间的头部开始,将有引用的对象拷贝在一段连续的内存空间中。其他的空间就是连续的空闲空间。

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



在进行具体操作时,JVM会进行分代回收。那么什么是分代回收呢?简单来说,JVM将堆空间分为新生代(young)和 老年代(old)两个区域,新生代(young)又分为Eden区,From区,To区三个区域。JVM会根据策略,对这几个区域进行操作,完成回收内存的任务。



在具体实现上,JAVA的垃圾回收器分为5种

  1. Serial 串行垃圾回收器:JVM早期的回收器,只有一个线程执行垃圾回收

  2. Parallel 并行垃圾回收器:多线程执行垃圾回收,但是当回收线程工作时,必须要停止用户线程的工作,否则可能会导致对象引用标记错乱。因此这个过程又被称为stop the world。

  3. CMS 并发垃圾回收器:在回收的某些阶段,回收线程和用户线程可以并发运作,因此对用户线程影响较小。

  4. G1 垃圾回收器:将整个堆空间分成多个子区域,在这些子区域上各自独立进行垃圾回收。在回收过程中回收线程和用户线程并发运行。G1综合了以前几种垃圾回收器的优点,在JDK9 中被设为默认的垃圾回收器。

  5. ZGC:新一代GC,在JDK11中被实验性的引入。ZGC的设计目标之一是stop the world 时间不超过10毫秒。

随着时间的发展JAVA的垃圾回收器利用多线程技术,通过对堆空间的精细划分,对用户程序的影响越来越小,性能越来越好。

用户头像

hifly

关注

还未添加个人签名 2018.03.08 加入

还未添加个人简介

评论

发布
暂无评论
第9周命题作业