垃圾收集器就是内存回收操作的具体实现,HotSpot 有 7 种。因为它们各有各的适用场景。有的属于新生代收集器,有的属于老年代收集器,所以一般都是搭配使用的。关于它们的简单介绍以及分类请见下图。
1.“单线程”操作。会产生“Stop The World”。 2.采用"Stopr the world"。 3.Serial 收集器是虚拟机在 Client模式下的默认新生代收集器,它的优势是简单高效,适合单 CPU 模式。 复制代码
1.其本身就是 Serial 收集器的多线程版本。虽然除此之外没什么创新之处,但它却是许多运行在 Server 模式下的虚拟机中的首选新生代收集器。 2.除了 Serial 收集器外,只有它能和 CMS 收集器搭配使用。 复制代码
1.新生代收集器,并行的多线程收集器。 2.使用复制算法, 3.可控制吞吐量(Throughput)。 复制代码
吞吐量 = 运行用户代码时间 / ( 运行用户代码时间 + 垃圾收集时间 )
可调节的虚拟机参数:
-XX:MaxGCPauseMillis
:最大 GC 停顿的秒数; -XX:GCTimeRatio
:吞吐量大小,一个 0 ~ 100 的数, 最大 GC 时间占总时间的比率 = 1 / (GCTimeRatio + 1)
; -XX:+UseAdaptiveSizePolicy
:一个开关参数,打开后就无需手工指定 -Xmn
, -XX:SurvivorRatio
等参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,自行调整。 1.Serial收集器的老年代版,同为单线程。 2.使用标记整理算法。 3.作为CMS收集容器的后备预案。 复制代码
1.Parallel Old收集器的老年代版,多线程。 2.使用标记-整理算法。 复制代码
1.CMS注重于服务的响应速度,希望系统停顿时间最短。 2.基于“标记-清除”算法实现的。【注1】 3.存在以下几点缺点: (1)CMS收集器对CPU资源非常敏感。 (2)CMS收集器无法处理浮动垃圾。 (3)由于基于标记-清除算法,所以会产生大量碎片 复制代码
【注1】 标记-清除算法步骤: 1.初始标记 2.并发标记 3.重新标记 4.并发清除
-XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction
之前对于 CMS 为什么要采用 标记 - 清除 算法十分的不理解,既然已经有了看起来更高级的 标记 - 整理 算法,那 CMS 为什么不用呢?最近想了想,感觉可能是这个原因,不过也不是很确定,只是个人的一种猜测。
标记 - 整理 会将所有存活对象向一端移动,然后直接清理掉边界以外的内存。这就意味着需要一个指针来维护这个分隔存活对象和无用空间的点,而我们知道 CMS 是并发清理的,虽然我们启动了多个线程进行垃圾回收,不过如果使用 标记 - 整理 算法,为了保证线程安全,在整理时要对那个分隔指针加锁,保证同一时刻只有一个线程能修改它, 加锁的这一过程相当于将并行的清理过程变成了串行的,也就失去了并行清理的意义了。
所以,CMS 采用了 标记 - 清除 算法。
特点:1.并行并发。 2.分代收集。 3.空间整合。 4.可预测的停顿。
1.初始标记 2.并发标记 3.最终标记 4.筛选回收 复制代码
-Xmx -Xms -Xmn -XX:SurvivorRatio=8
-XX:PretenureSizeThreshold
:单位是字节;
-XX:MaxTenuringThreshold
设定值后,会被晋升到老年代, -XX:MaxTenuringThreshold
默认为 15;