jvm-3学习教程

jvm学习之gc垃圾回收机制

1、什么是垃圾回收?

堆中使用对象,但是不能一直放在那里,会占内存,所以需要垃圾回收,释放多余内存,从而保证程序的正常运行。

2、垃圾回收之前应该判断到底什么是垃圾?

  • 引用计数法:对象保存着被引用的次数,被引用一次就+1,删除引用一次-1,如果引用个数为0,那么会被回收,但是有个问题无法解决

堆中A,B没有别的对象引用,双方互相依赖,这样的话,两个对象永远无法被回收

  • 可达性分析(reachable anaylisis)

  从GC Roots往下追踪,如果在roots的引用链上,则表示对象是可达的,否则,表示对象不可达,对象是可以回收的

   GC Roots都有哪些:

  • 虚拟机栈中的对象(线程正在使用的对象)
  • 方法区中的对象

3、垃圾回收的算法

  •  标记清除(mark-swaap)

清除前

 清除后

可以看出来:效率并不是太高,同时回收之后的空间并不是连续的,造成内存空间过碎,如果有一个比较大的对象需要分配对象可能会造成又一次内存回收的动作,造成系统的再次使用。

  • 复制算法 

将内存分为相等的两份,回收内存的时候,将A区的存活对象放到B区,然后一次性的将A区的所有内存回收,代价是:内存被分为两份,可用内存减少一半。

  • 标记压缩法(mark-compact)

  • 分代清除法

新生代:区域内的对象存活时间较短,大部分对象使用一次都会被回收,所以使用复制算法即可

老生代:存活的对象很高,同时也没有空间使用复制算法,所以使用标记清除法或者标记压缩法,效果更好。

4、垃圾回收器 

  •  serial回收器(串行回收器)

使用一个线程使用分代清除法回收对象,回收过程中会出现stop world

  • parnew回收器(并行回收器)

使用多线程使用分代清除法回收对象

  • CMS回收器(concurrentMarkSweep)

目标:最短回收停顿时间

分为四个步骤:

  • 初始标记 inital mark
  • 并发标记 concurrent mark
  • 重新标记 remark
  • 并发清除 concurrent sweep

初始标记:搜索gc roots能够直接关联的对象,时间很短,需要stop the world

并发标记:进行gc roots tracing,不是直接使用的对象,时间较长,可以与应用程序并发执行

重新标记:并发标记过程中程序的对象引用变化,需要矫正清除对象

并发清除:清除对象,与应用程序可以同时执行

  •  G1的垃圾回收

相似度与CMS相似度极高,不过不同是G1可以指定垃圾回收的时间,不需要一次性全部回收,因为g1是将内存分为若干个region,然后根据垃圾多少进行排列,这样的话是可以执行回收多少个region,从而实现垃圾回收时间的预测

原文地址:https://www.cnblogs.com/zhangchiblog/p/11874359.html