jvm中的垃圾收集器
垃圾收集器就是内存垃圾回收的具体实现了,垃圾收集器有很多种,包括串行垃圾收集器,并行垃圾收集器、CMS(并发)垃圾收集器、G1垃圾收集器等。
一、串行垃圾收集器
Serial 收集器
这个收集器是个单线程的收集器,但他的单线程意义不仅仅是说明它只会使用一个cpu或者一条收集线程去完成垃圾收集工作,更重要的是它在收集垃圾的时候,必须暂停掉其他所有工作线程,直到它收集结束。而对于现在这个环境而言,这种收集器是不能被接受的。
二、并行垃圾收集器
2.1 ParNew 收集器
这个收集器 除了改为多线程外,与Serial收集器没有太多的区别。
2.2 Parallel Scavenge 收集器
Parallel Scavenge收集器是一个新生代收集器,它也是使用了复制算法,也是并行的多线程收集器,与ParNew不同的是提供了两个参数可以精准控制吞吐量,分别是控制最大垃圾收集停顿时间 -XX:MaxGcPauseMillis 参数 以及直接设置吞吐量大小的 -XX:GCTimeRatio参数。
吞吐量:吞吐量 = 运行用户代码的时间/(运行用户代码的时间 + 垃圾回收的时间)
-XX:MaxGcPauseMillis :允许设置一个大于0ms的值,收集器将尽可能的保证内存回收花费的时间不超过设定的值。不过不是设置的越小就越快,GC停顿时间缩短是牺牲吞吐量和新生代空间来换取的,所以设置的停顿时间越小,吞吐量也会下来。
-XX:GCTimeRatio:参数的值应当是一个大于0,小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。
由于与吞吐量关系密切,所以Parallel Scavenge 收集器 也被称为 吞吐量优先 收集器。除了上面两个参数外,Parallel Scavenge 收集器还有一个参数 -XX:+UseAdaptiveSizePolicy,这个参数是一个开关参数(boolean参数),当这个参数打开时,就不需要手动指定新生代的大小、Eden和Survivor区的比例、晋升老年代对象大小等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态的调整这些参数以提供最合适的停顿时间或者最大的吞吐量。这种调节方式成为GC自适应的调节策略。这也是和ParNew调节器最大的区别。
三、CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。我们的系统希望响应时间短,速度快,以给用户带来好的体验,CMS收集器就非常适合。
运作过程包括四个步骤:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
虽然CMS停顿时间短,能够并发收集,但是缺点还是很多的。
- CMS对CPU资源非常敏感。在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程(cpu资源)而导致应用程序变慢,总吞吐量会降低。
- CMS无法清理浮动垃圾,由于CMS运行的时候还会有新的垃圾生成,这一部分垃圾在标记之后,无法在这次垃圾收集中处理掉他们,只能等待下一次垃圾回收,这样的垃圾就称为浮动垃圾。
- 会有大量的空间碎片,毕竟是标记 - 清除算法。
四、G1收集器(主角登场,重点)
G1(Garbage Frist)收集器是一款面向服务端应用的垃圾收集器,它具有以下特点:
特点:
- 并行与并发:G1收集器能充分利用cpu、多核环境的优势,使用多个cpu来缩短停顿时间
- 分代收集:自动判断需要使用什么垃圾收集算法。
- 空间整合:运行期间不会产生内存碎片,收集后能提供规整的可用内存。
- 可预测的停顿:能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
G1收集器取消了年轻代、老年代的物理划分,将堆划分成若干个区域(Region),这些区域中包含了逻辑上的年轻代,老年代。
G1收集器提供了三种垃圾回收模式:Young GC、Mixed GC、Full GC,在不同的条件下触发。
YoungGC:主要是对Eden区进行GC,它在eden空间耗尽时会被触发。
Eden空间的数据移动到Survivor空间中,如果Survivor空间不够,Eden空间的 部分
数据会直接晋升到年老代空间。
Survivor区的数据移动到新的Survivor区中,也有部分数据晋升到老年代空间中。
最终Eden空间的数据为空,GC停止工作,应用线程继续执行。
Mixed GC:当越来越多的对象晋升到老年代oldregion时,为了避免堆内存被耗尽,虚拟机会触 发一个混合的垃圾收集器,即MixedGG, 该算法并不是一个Old GC,除了回收整个YoungRegion,会回收–部分的OldRegion,这里需要注意:是一部分老年代,而不是全部老年代,可以选择哪些oldregion进行收集,从而可以对垃圾回收的耗时时间进行控制。
也要注意的是MixedGC并不是FullGC。
MixedGC什么时候触发?由参数-X:InitiatingHeapOccupancyPercent=n决定。默认:45%,该参数的意思是:当老年代大小占整个堆大小百分比达到该阀值时触发。
它的GC步骤分2步:
1.全局并发标记( global concurrent marking )
2.拷贝存活对象( evacuation )
Full GC:是清理整个堆空间—包括年轻代和永久代。