jvm——垃圾回收机制

《深入理解Java虚拟机》是一本能让java开发者废寝忘食的书。
最初拿到这本书,自己还是一个完全懵懂、“知其然而不知其所以然”的java菜鸟,现在可能好一点了,这本书也来来回回翻了好几遍,对jvm有了一定的认识。最近要找工作,又重新学习了下,总结一下一些基本的知识点。
本文主要总结一下jvm的垃圾回收相关内容

问题

  1. 哪些内存需要回收机制
  2. 如何判定该对象已经死亡(可以回收)
  3. 垃圾收集算法有哪几种
  4. HotSpot是如何实现
  5. 有哪几种垃圾收集器

哪些内存需要回收机制

根据jvm运行时数据区域的划分,我们可以知道,程序计数器、虚拟机栈、本地方法栈,这三块区域,随线程而生,随线程而灭,是不需要垃圾回收器来处理的。
java堆、方法区,是线程共有的,并且占用的大小不确定,所以,需要使用垃圾回收器来回收那些已经没有用的对象(堆中)、常量(方法区)、类(方法区)。

如何判定该对象已经死亡(可以回收)

对于java堆中的对象,如何判断是否可以回收,一般有两种方法:

  1. 引用计数算法,存在着无用的循环引用问题,java没有采用这种方法;
  2. 可达性分析算法,是java语言采用的方式。

可达性分析算法:Reachablility Analysis,通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连,即从GC Roots到这个对象不可达,则证明该对象是不可用的,是可回收的对象。

java语言中,可以作为GC Roots的对象包括以下几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象
  2. 方法区中类静态(static)属性引用的对象
  3. 方法区中常量(final static)引用的对象
  4. 本地方法栈中JNI(Native本地方法)引用的对象

这里穿插一个小知识:对引用概念的扩充,强引用,软引用,弱引用,虚引用的介绍,主要用于一些系统的缓存功能,解决的问题是,当内存空间充足,留着这些引用关联的对象;若内存不足,则回收它们。

对象回收的过程:

  1. 某对象与GC Roots之间不可达,它被第一次标记
  2. 此时看此对象是否有必要执行finalize()方法(Object类的方法);
    2.1 对象没有覆盖该方法,或者该方法已经被虚拟机调用过,则不用再执行了;(然后了???可能就被回收了)
    2.2 对象需要执行该方法,被放置到F-Queue队列中等待被虚拟机线程执行,在此方法内,让自己和引用链重新连接,是唯一解救自己的方法
  3. 稍后GC将对F-Queue队列中的对象进行第二次小规模的标记,此时,如果对象拯救了自己,它重新与引用链连接上,则会在这次标记过程中被移除“即将回收”的集合,如果这轮也被标记了,基本就要被回收了。

回收方法区

  1. 方法区,也就是HotSpot的永久代,收集的“性价比”很低,很少需要回收的,但是回收是必要的
  2. 回收的主要内容:废弃的常量和无用的类
  3. 大量使用反射、动态代理、CGLIB等字节码类生成框架、动态JSP、OSGI这类频繁自定义classloader的场景,就需要永久代的垃圾回收,避免内存溢出。

垃圾收集算法有哪几种

  1. 标记-清除算法
  2. 复制算法
  3. 标记-整理算法
  4. 分代收集算法(我觉得这个不算一种算法吧,不应该放在这里)

HotSpot是如何实现

使用分代收集的思想,把新生代内存区域划分为8:1:1,使用复制算法;老年代使用“标记-清理”或者“标记-整理”算法。

有哪几种垃圾收集器

这里只是列出这几种垃圾回收器,具体关于回收器的内容需要多读几遍才能看懂。

  1. Serial收集器(新生代,单线程,较严重Stop the World)
  2. ParNew收集器(新生代,并行多线程,较严重Stop the World)
  3. Parallel Scavenge收集器(新生代,并行多线程,吞吐量优先)
  4. Serial Old 收集器(老年代,单线程,标记-整理)
  5. Parallel Old 收集器(老年代,多线程,标记-整理,与Parallel Scavenge收集器搭配吞吐量优先,吞吐量优先)
  6. CMS 收集器(老年代,标记-清除,并发,低停顿)
  7. G1收集器(最先进,新生代/老年代,并发,整体看是“标记-整理”,局部看“复制”,低停顿)

内存分配与回收策略

  1. 对象优先分配在Eden上
  2. 大对象直接进入老年代
  3. 长期存活的对象进入老年代
  4. 动态对象年龄判定
  5. 空间分配担保
文章目录
  1. 1. 问题
    1. 1.1. 哪些内存需要回收机制
    2. 1.2. 如何判定该对象已经死亡(可以回收)
    3. 1.3. 回收方法区
    4. 1.4. 垃圾收集算法有哪几种
    5. 1.5. HotSpot是如何实现
    6. 1.6. 有哪几种垃圾收集器
    7. 1.7. 内存分配与回收策略
|