You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ParNew收集器是Serial收集器的多线程版本。除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一样。这两种收集器在实现上也共用了相当多的代码。ParNew收集器是许多运行在Server模式下的虚拟机中首选的新生代收集器。
Parallel Scavenge收集器
Parallel Scavenge提供两个参数精确控制吞吐量,-XX:MaxGCPauseMillis控制最大垃圾收集停顿时间和-XX:GCTimeRatio设置吞吐量大小 。MaxGCPauseMillis允许的值是一个大于零的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。GC停顿时间缩小是以牺牲吞吐量和新生代空间来换取的,也就是要使停顿时间更短,需要使新生代的空间减小,这样垃圾回收的频率会增加,吞吐量也降下来了。
Serial Old收集器
Serial Old是Serial收集器的老年代版本,使用标记-整理算法的单线程收集器。对于Client模式,主要在于给Client模式下的虚拟机使用;而对于Server模式,在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用,或作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。
Parallel Old收集器
初始标记(Initial Marking)
初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程,但耗时很短。
并发标记(Concurrent Marking)
并发标记阶段是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行。
最终标记(Final Marking)
最终标记阶段是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,这阶段需要停顿线程,但是可并行执行。
筛选回收(Live Data Counting and Evacuation)
筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划,这个阶段其实也可以做到与用户程序一起并发执行,但是因为只回收一部分Region,时间是用户可控制的,而且停顿用户线程将大幅提高收集效率。
1、简介
a、意义
b、判断
c、特性
2、常用JVM参数配置
对于CMS GC时出现promotion failed和concurrent mode failure的调优:
产生原因:
3、垃圾收集算法
a、引用计数
每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1;当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明已经不存在指向该对象的指针了,所以它可以被安全的销毁了。
b、标记-清除
标记和清除两个阶段,标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象。
c、复制算法
为了解决效率问题,复制算法将可用内存按容量划分为大小相等的两块,每次只是用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。
实际上新生代中的对象98%是朝生夕死的,并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor。回收时,将Eden和Survivor中还存活着的兑现个一次性地拷贝到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor的空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%,只有10%的内存是会被浪费的。
d、标记整理
标记-整理(Mark-Compact)算法不直接对可回收对象进行清理,而是让所有可用的对象都向一端移动,然后直接清理掉边界意外的内存。即在清理无用对象完成后让所有存活的对象都向一端移动,并更新引用其对象的指针。缺点:在标记-清除的基础上还需进行对象的移动,成本相对较高,好处则是不会产生内存碎片。
e、分代收集
据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。
新生代使用复制和标记-清除垃圾收集算法。
年老代中的对象一般都是长生命周期对象,对象的存活率比较高,因此在年老代中使用标记-整理垃圾回收算法。
java虚拟机内存中的方法区在Sun HotSpot虚拟机中被称为永久代,是被各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。永久代垃圾回收比较少,效率也比较低,但是也必须进行垃圾回收,否则会永久代内存不够用时仍然会抛出OutOfMemoryError异常。
3、垃圾收集器
串行垃圾回收:
串行垃圾回收器通过持有应用程序所有的线程进行工作。它为单线程环境设计,只使用一个单独的线程进行垃圾回收,通过冻结所有应用程序线程进行工作,所以可能不适合服务器环境。它最适合的是简单的命令行程序。通过JVM参数-XX:+UseSerialGC可以使用串行垃圾回收器。
并行垃圾回收:
并行垃圾回收器也叫做 throughput collector 。它是JVM的默认垃圾回收器。与串行垃圾回收器不同,它使用多线程进行垃圾回收。不过同的是:当执行垃圾回收的时候它也会冻结所有的应用程序线程。
并发垃圾回收:
并发标记垃圾回收使用多线程扫描堆内存,标记需要清理的实例并且清理被标记过的实例。相比并行垃圾回收器,并发标记扫描垃圾回收器使用更多的CPU来确保程序的吞吐量。如果我们可以为了更好的程序性能分配更多的CPU,那么并发标记上扫描垃圾回收器是更好的选择相比并发垃圾回收器。通过JVM参数 XX:+USeParNewGC 打开并发标记扫描垃圾回收器。
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
Serial收集器
Serial收集器是最基本、发展历史最悠久的单线程收集器,但它的“单线程”的意义并不仅仅说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作。重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。
ParNew收集器
ParNew收集器是Serial收集器的多线程版本。除了使用多条线程进行垃圾收集之外,其余行为包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial收集器完全一样。这两种收集器在实现上也共用了相当多的代码。ParNew收集器是许多运行在Server模式下的虚拟机中首选的新生代收集器。
Parallel Scavenge收集器
Parallel Scavenge收集器是新生代使用复制算法的并行多线程收集器。它的关注点与其它收集器不同,CMS等收集器的关注点尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput),也被称为吞吐量优先收集器。
所谓吞吐量就是CPU用于运行用户代码时间与CPU总消耗时间的比值。吞吐量=运行用户代码时间/运行用户代码时间+垃圾收集时间。其停顿时间短,适合需要与用户交互的程序,良好的响应速度能提升用户体验,高吞吐量则可以高效率地利用CPU时间,尽快完成程序的运算任务。其主要适合在后台运算而不需要太多交互的任务。
Parallel Scavenge提供两个参数精确控制吞吐量,-XX:MaxGCPauseMillis控制最大垃圾收集停顿时间和-XX:GCTimeRatio设置吞吐量大小 。MaxGCPauseMillis允许的值是一个大于零的毫秒数,收集器将尽力保证内存回收花费的时间不超过设定值。GC停顿时间缩小是以牺牲吞吐量和新生代空间来换取的,也就是要使停顿时间更短,需要使新生代的空间减小,这样垃圾回收的频率会增加,吞吐量也降下来了。
Serial Old收集器
Serial Old是Serial收集器的老年代版本,使用标记-整理算法的单线程收集器。对于Client模式,主要在于给Client模式下的虚拟机使用;而对于Server模式,在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用,或作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。
Parallel Old收集器
Parallel Old是Parallel Scavenge收集器的老年代版本,使用“标记-整理”算法的多线程收集器。在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge+Parallel Old收集器。
CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的基于“标记—清除”算法的收集器。主要的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间短,以给用户较好体验。
其运行整个过程分为4个步骤:
由于整个过程中耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,从总体上来说,CMS收集器的内存回收过程是与用户线程一起并发执行的。
优点:
缺点:
G1收集器
G1(Garbage-First)是一款面向服务端应用的垃圾收集器。
G1具备如下特点。
在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。
G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region(这也就是Garbage-First名称的来由)。这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。
G1收集器的运作大致可划分为以下几个步骤:
4、内存分配与回收
参考文献:
周志明. 深入理解 Java 虚拟机: JVM 高级特性与最佳实践[J]. 2010.
The text was updated successfully, but these errors were encountered: