深入理解java虚拟机-垃圾收集器

怎么判定一个对象是死的呢?

目前有引用计数法,和根搜索法

引用计数法 即改对象被引用的次数,弊端 循环引用的问题,如 studenta.instance=studentb,studentb.instance=studenta

Hotspot采用的是根搜索法(可达分析法),当一个对象到GCRoot 没任何引用相连,则该对象可被回收

可做GCRoot,有静态变量,栈中引用对象,常量引用,本地方法栈引用的对象.

 

垃圾回收主要分三类

1:标记清除算法,MarkSweep,把所有垃圾对象做标记,然后直接清楚

2:复制算法,比如分两块同等大小内存,把A中存活的对象复制到B,然后清除A,

3:标记整理算法,MarkCompact,把垃圾对象清楚后,然后向一段移动,以防止内存碎片。

JVM中进行垃圾回收,会出现stop the world 即停顿所有正在工作的线程,不然引用关系会发生变化。

安全点:虚拟机需要知道哪些对象是引用,使用一个为OopMap数据结构来进行记录,类加载完后HotSpot就把对象内什么偏移量上是什么类型数据计算出来,JIT编译中也会记录下哪些位置是引用,Hotspot可以通过oopmap完成快速gcroot枚举,只有在一些特定的地方才会生成oopmap(称为安全点)方法调用,循环跳转,异常跳转等才会产生安全点。当方式gc的时候所有线程去轮训一个flag,如果出现gc flag,则所有线程到最近的安全点停下。

安全区域:如果线程处于阻塞或者sleep的时候无法到安全点的,这个时候线程标识自己进入了安全区域,当出安全区域的时候

要检查是否在进行gcroot枚举,如果是继续等待。

新时代收集器

serial:单线程收集器,复制算法(这个参数新时代老年代都是串行) -XX:+UserSerialGC

 

parNew:是serial的多线程版本 复制算法 (新时代使用一般搭配CMS使用) -XX:+UseParNewGC

同时可以指定-XX:ParallelGCThreads来设置并行的线程数量

 

parallel scavenge:复制算法,也是并行的多线程版本,但是侧重点不一样,这个收集器注重throughtput(吞吐量)

即cpu运行用户代码时间/(用户代码+垃圾回收)

可以通过-XX:MaxGCPauseMillis来设置最大停顿时间

也可以设置吞吐量 -XX:GCTimeRatio来设置吞吐量默认99

由jvm来动态调整新时代大小和eden和survivor比例   -XX:UseAdaptiveSizePolicy(默认开启1.7)

老年代收集器

serial old收集器单线程手机

parallel old 多线程老年代收集器 (新老都是用parallel )  -XX:+UserParallelOldGC

CMS 并发(用户程序和垃圾并发)老年代收集器

猜你喜欢

转载自blog.csdn.net/woyixinyiyi/article/details/84519144