如果说收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现 复制代码
吞吐量:表示系统减去系统回收时间占总时间的比率,比如,系统运行了100秒,垃圾回收占用了1秒,那么吞吐量就是(100-1)/100 = 99%
垃圾回收消耗:和吞吐量相反,垃圾回收器消耗指的是垃圾回收器耗时与系统运行总时间的比值
停顿时间:指垃圾回收器运行的时候,系统停顿的时间
回收频率:指垃圾回收器多长时间运行一次,一般来说,对于固定的应用而言,垃圾回收器的频率应该越低越好,通常增加堆空间可以有效的降低垃圾回收发生的频率,但是可能会增加回收产生的停顿时间
反应时间:当一个内存对象被标记为垃圾对象后到这个对象真正回收所产生的时间
根据这几个指标,我们可以知道,垃圾回收性能好的表现是:吞吐量高,垃圾回收消耗低,停顿时间少,回收频率低,反应时间快。但是,并没有这么完美的性能表现,这几个指标有些是互斥的,比如要降低回收频率,就要扩大空间,但是就会增加停顿时间;同样要想反应时间快,就必须要提高回收频率。所以,这些性能的追求就是一个博弈平衡的过程,我们可以根据我们追求的某一方面来进行调优,比如,对于客户端应用而言,应该尽可能降低其停顿时间,给用户良好的使用体验,为此,可以牺牲垃圾回收的吞吐量;对服务端程序来说,可能会更加关注吞吐量。
串行收集器是最古老、最稳定以及效率高的垃圾回收器。
使用单线程进行垃圾回收,独占式垃圾回收
串行垃圾回收器通过持有应用程序所有的线程进行工作。它为单线程环境设计,只使用一个单独的线程进行垃圾回收,通过冻结所有应用程序线程进行工作,所以可能不适合服务器环境
它最适合的是简单的命令行程序(单CPU、新生代空间较小及对暂停时间要求不是非常高的应用)。是client级别默认的GC方式。
新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程中会Stop The World(服务暂停)
参数控制: -XX:+UseSerialGC 串行收集器
ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩
只有他能与CMS收集器配合工作。
参数控制:
-XX:+UseParNewGC ParNew收集器 -XX:ParallelGCThreads 限制线程数量 -XX:+UseParNewGC:新生代使用并行收集器,老年代使用串行回收器。 -XX:+UseConcMarkSweepGC:新生代使用并行回收器,老年代使用CMS
并行收集器工作时的线程数量可以使用 -XX:ParallelGCThreads 参数指定。一般最好与CPU数量相当,避免过多的线程数,影响垃圾收集性能
在默认情况下,当CPU数量小于8个时,ParallelGCThreads 的值等于 CPU 数量;当 CPU 数量大于8个时,ParallelGCThreads 的值等于 3+[(5*CPU_Count)/8]
并行垃圾回收器也被称之为:吞吐量收集器(throughput collector)
他是jvm默认的垃圾回收器
与串行垃圾回收器不同的是它使用多线程进行垃圾回收,使用的是复制算法
相似的是执行垃圾回收的时候,他也会冻结所有的应用程序线程
使用与CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式。
参数控制
-XX:+UseParallelGC 新生代使用并行回收收集器,老年代使用串行回收器。 -XX:ParallelGCThreads=4 指定线程数
Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。这个收集器是在JDK 1.6中才开始提供
参数控制
-XX:+UseParallelOldGC 使用Parallel收集器+ 老年代并行
相比并行垃圾回收器,并发标记扫描垃圾回收器使用更多的CPU来确保程序的吞吐量。如果我们可以为了更好的程序性能分配更多的CPU,那么并发标记上扫描垃圾回收器是更好的选择相比并发垃圾回收器。
通过JVM参数 XX:+USeParNewGC 打开并发标记扫描垃圾回收器。
并发收集、低停顿
产生大量空间碎片、并发阶段会降低吞吐量
组合 | 新生代GC策略 | 老年老代GC策略 | 说明 |
---|---|---|---|
组合1 | Serial | Serial Old | Serial和Serial Old都是单线程进行GC,特点就是GC时暂停所有应用线程。 |
组合2 | Serial | CMS+Serial Old | CMS(Concurrent Mark Sweep)是并发GC,实现GC线程和应用线程并发工作,不需要暂停所有应用线程。另外,当CMS进行GC失败时,会自动使用Serial Old策略进行GC |
组合3 | ParNew | CMS | 使用 -XX:+UseParNewGC选项来开启。ParNew是Serial的并行版本,可以指定GC线程数,默认GC线程数为CPU的数量。可以使用-XX:ParallelGCThreads选项指定GC的线程数。如果指定了选项 -XX:+UseConcMarkSweepGC选项,则新生代默认使用ParNew GC策略。 |
组合4 | ParNew | Serial Old | 使用 -XX:+UseParNewGC选项来开启。新生代使用ParNew GC策略,年老代默认使用Serial Old GC策略。 |
组合5 | Parallel Scavenge | Serial Old | Parallel Scavenge策略主要是关注一个可控的吞吐量:应用程序运行时间 / (应用程序运行时间 + GC时间),可见这会使得CPU的利用率尽可能的高,适用于后台持久运行的应用程序,而不适用于交互较多的应用程序。 |
组合6 |Parallel Scavenge |Parallel Old | Parallel Old是Serial Old的并行版本 | 组合7 |G1GC | G1GC |-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC #开启; -XX:MaxGCPauseMillis=50 #暂停时间目标; -XX:GCPauseIntervalMillis=200 #暂停间隔目标; -XX:+G1YoungGenSize=512m #年轻代大小; -XX:SurvivorRatio=6 #幸存区比例 | 复制代码
优秀的博客