1、G1会成为新的默认垃圾收集器吗?
Java只有一个垃圾收集器,而事实上它有4个。Java9中,仍有一个运行提议,关于替换由Java7引入的G1默认垃圾收集器(并行/吞吐量收集)的讨论。
通常来说,G1被设计来更好地支持大于4GB的堆,并且不会造成频繁的GC暂停,但当暂停发生时,往往会处理更长时间。
2、jvm垃圾收集器为什么
JVM中垃圾的回收由垃圾收集器进行,随着JDK的不断升级,垃圾收集器也开发出了各种版本,垃圾收集器不断优化的动力,就是为了实现更短的停顿。
下面是7种不同的分代收集器,如果两个收集器之间有连线,则表示它们之间可以搭配使用;所处的区域表示属于新生代还是老年代收集器。

1.Serial 收集器 (新生代)
最基本、历史最悠久(JDK1.3.1之前),这是一个单线程的收集器,当该收集器运行时必须暂停其他所有的工作线程,直到它收集结束。
收集过程:暂停所有线程
算法:复制算法
优点:简单高效,拥有很高的单线程收集效率
应用:Client模式下的默认新生代收集器
2.ParNew 收集器 (新生代)
Serial 的多线程版本,使用多线程进行垃圾收集
收集过程:与用户线程并发
算法:复制算法
优点:在CPU多的情况下,拥有比Serial更好的效果。单CPU环境下Serial效果更好
应用:许多运行在Server模式下的虚拟机中首选的新生代收集器
3.Parallel Scavenge 收集器(新生代)
Parallel Scavenge收集器的目标是达到一个可控制的吞吐量
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)
控制吞吐量的参数:最大垃圾收集停顿时间 -XX:MaxGCPauseMillis ; 直接设置吞吐量大小:-XX:GCTimeRatio。
MaxGCPauseMillis 的值为一个大于0的毫秒数, 最大停顿时间的缩短是以牺牲吞吐量和新生代空间来换取的。
GCTimeRatio 的值为一个大于0且小于100的整数。例如:-XX:GCTimeRatio=9 我们要求应用程序线程在整个执行时间中至少9/10是活动的(因此,GC线程占用其余1/10)
-XX:+UseAdaptiveSizePolicy:开启GC自适应调节策略,自动设置新生代大小、Eden与Survior区的比例、晋升老年代对象年龄等细节参数
应用:适合在后台运算而不需要太多交互的任务
4.Serial Old 收集器 (老年代)
Serial收集器的老年代版本,也是一个单线程的收集器,使用标记-整理算法
收集过程:暂停所有线程
算法:标记-整理算法
应用:主要意义是Client模式下的收集器,如果在Server模式下还有:a. JDK1.5之前的版本中与Parallel Scavenge搭配使用,b. 作为CMS收集器的后背预案在并发收集时使用
5. Parallel Old 收集器 (老年代)
Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。
收集过程:多线程
算法:标记-整理算法
应用:在注重吞吐量及CPU资源敏感的场合,可以优先考虑Parallel Scavenge加Parallel Old收集器
6. CMS 收集器 (老年代)
以获取最短回收停顿时间为目标,基于“标记-清除”算法
收集过程:初始标记-->并发标记-->重新标记-->并发清除
初始标记、重新标记两个步骤仍需要“Stop The World” : 初始标记仅仅只是标记一下GC
Roots能直接关联到的对象,速度很快;并发标记就是进行GC Roots
Tracing的过程;重新标记是为了修正并发标记期间因用户程序继续运作,而导致标记产生变动的那一部分对象的标记记录。
整个过程中耗时最长的是并发标记和并发清除,这两个过程都可以与用户线程一起工作。所以总体上说CMS收集器内存回收过程与用户线程一起并发执行。
算法:标记-清除 算法
缺点:1,对cpu资源敏感,默认启动的回收线程数是(cpu数量+3)/4,当cpu数较少的时候,会分掉大部分的cpu去执行收集器线程,影响用户,降低吞吐量。
2,无法处理浮动垃圾,浮动垃圾即在并发清除阶段因为是并发执行,还会产生垃圾,这一部分垃圾即为浮动垃圾,要等下次收集。
3,因为使用的是“标记-清除”算法,会产生碎片。
7. G1收集器 (整个Java堆:包括新生代和老年代)
特点:并行与并发、分代收集、空间整合、可预测的停顿
G1将整个java堆(包括新生代和老生代)划分为多个大小固定的独立区域,并跟踪这些区域的垃圾堆积程度,在后台维护一个优先列表,每次根据允许的收集时间,优先回收垃圾最多的区域。
但这样回收有一个问题:对象分配在某个区域中,但并非只被本区域的其他对象引用,而是可以与整个Java堆任意的对象发生引用关系。在做可达性分析的时候,如何避免扫描整个堆呢?
解决:区域之间的对象引用,以及其他收集器中新生代与老年代之间的对象引用,虚拟机都是使用Remembered Set来避免全堆扫描,在Remembered Set中记录对象的引用。
收集过程:初始标记-->并发标记-->最终标记-->筛选回收。与CMS不同的是,在最终标记阶段,需要停顿线程,但是可并发执行;筛选回收阶段,对各个区域的回收价值和成本进行排序,按照用户所期望的回收时间进行垃圾回收,这个阶段也可以并发执行。
3、HotSpot JVM支持哪些垃圾收集器
按线程
单线程:Serial、SerialOld
多线程:ParNew、Parallel Scavenge、Parallel Old、CMS、G1
按适用代
新生代: Serial、ParNew、Parallel Scavenge
老年代: SerialOld、CMS 、Parallel Old
G1可以在新生代和老年代使用
常见的组合
ParNew+CMS
Parallel Scavenge+Parallel Old
4、JVM的垃圾算法有哪几种
一、垃圾收集器概述
如上图所示,垃圾回收算法一共有7个,3个属于年轻代、三个属于年老代,G1属于横跨年轻代和年老代的算法。
JVM会从年轻代和年老代各选出一个算法进行组合,连线表示哪些算法可以组合使用
二、各个垃圾收集器说明
1、Serial(年轻代)
年轻代收集器,可以和Serial Old、CMS组合使用
采用复制算法
使用单线程进行垃圾回收,回收时会导致Stop The World,用户进程停止
client模式年轻代默认算法
GC日志关键字:DefNew(Default New Generation)
图示(Serial+Serial Old)
2、ParNew(年轻代)
新生代收集器,可以和Serial Old、CMS组合使用
采用复制算法
使用多线程进行垃圾回收,回收时会导致Stop The World,其它策略和Serial一样
server模式年轻代默认算法
使用-XX:ParallelGCthreads参数来限制垃圾回收的线程数
GC日志关键字:ParNew(Parallel New Generation)
图示(ParNew + Serail Old)

3、Paralle Scavenge(年轻代)
新生代收集器,可以和Serial Old、Parallel组合使用,不能和CMS组合使用
采用复制算法
使用多线程进行垃圾回收,回收时会导致Stop The World
关注系统吞吐量
-XX:MaxGCPauseMillis:设置大于0的毫秒数,收集器尽可能在该时间内完成垃圾回收
-XX:GCTimeRatio:大于0小于100的整数,即垃圾回收时间占总时间的比率,设置越小则希望垃圾回收所占时间越小,CPU能花更多的时间进行系统操作,提高吞吐量
-XX:UseAdaptiveSizePolicy:参数开关,启动后系统动态自适应调节各参数,如-Xmn、-XX:SurvivorRatio等参数,这是和ParNew收集器重要的区别
GC日志关键字:PSYoungGen
4、Serial Old(年老代)
年老代收集器,可以和所有的年轻代收集器组合使用(Serial收集器的年老代版本)
采用 ”标记-整理“算法,会对垃圾回收导致的内存碎片进行整理
使用单线程进行垃圾回收,回收时会导致Stop The World,用户进程停止
GC日志关键字:Tenured
图示(Serial+Serial Old)
5、Parallel Old(年老代)
年老代收集器,只能和Parallel Scavenge组合使用(Parallel Scavenge收集器的年老代版本)
采用 ”标记-整理“算法,会对垃圾回收导致的内存碎片进行整理
关注吞吐量的系统可以将Parallel Scavenge+Parallel Old组合使用
GC日志关键字:ParOldGen
图示(Parallel Scavenge+Parallel Old)
6、CMS(Concurrent Mark Sweep年老代)
年老代收集器,可以和Serial、ParNew组合使用
采用 ”标记-清除“算法,可以通过设置参数在垃圾回收时进行内存碎片的整理
1、:默认开启,FullGC时进行内存碎片整理,整理时用户进程需停止,即发生Stop The World
2、CMSFullGCsBeforeCompaction:设置执行多少次不压缩的Full GC后,执行一个带压缩的(默认为0,表示每次进入Full GC时都进行碎片整理)
CMS是并发算法,表示垃圾回收和用户进行同时进行,但是不是所有阶段都同时进行,在初始标记、重新标记阶段还是需要Stop the World。CMS垃圾回收分这四个阶段
1、初始标记(CMS Initial mark) Stop the World 仅仅标记一下GC Roots能直接关联到的对象,速度快
2、并发标记(CMS concurrent mark) 进行GC Roots Tracing,时间长,不发生用户进程停顿
3、重新标记(CMS remark) Stop the World 修正并发标记期间因用户程序继续运行导致标记变动的那一部分对象的标记记录,停顿时间较长,但远比并发标记时间短
4、并发清除(CMS concurrent sweep) 清除的同时用户进程会导致新的垃圾,时间长,不发生用户进程停顿
适合于对响应时间要求高的系统
GC日志关键字:CMS-initial-mark、CMS-concurrent-mark-start、CMS-concurrent-mark、CMS-concurrent-preclean-start、CMS-concurrent-preclean、CMS-concurrent-sweep、CMS-concurrent-reset等等
缺点
1、对CPU资源非常敏感
2、CMS收集器无法处理浮动垃圾,即清除时用户进程同时产生的垃圾,只能等到下次GC时回收
3、因为是使用“标记-清除”算法,所以会产生大量碎片
图示

7、G1
G1收集器由于没有使用过,所以从网上找了一些教程供大家了解
并行与并发
分代收集
空间整合
可预测的停顿
5、ParNew 和 PSYoungGen 和 DefNew 是一个东西么?
查了一下书:是这样的。串行收集器:DefNew:是使用-XX:+UseSerialGC(新生代,老年代都使用串行回收收集器)。并行收集器:ParNew:是使用-XX:+UseParNewGC(新生代使用并行收集器,老年代使用串行回收收集器)或者-XX:+UseConcMarkSweepGC(新生代使用并行收集器,老年代使用CMS)。PSYoungGen:是使用-XX:+UseParallelOldGC(新生代,老年代都使用并行回收收集器)或者-XX:+UseParallelGC(新生代使用并行回收收集器,老年代使用串行收集器)garbage-first heap:是使用-XX:+UseG1GC(G1收集器)
6、生产中 java 垃圾回收为什么不用g1
垃圾回收是Java语言的一大特性,方便了编程,是以消耗性能为代价的,Java语言对内存的分配管理是通过JVM内部机制决定的。
Java虚拟机中有个称之为垃圾回收器的东西,实际上这个东西也许真正不存在,或者是已经集成到JVM中了,但这无关紧要,仍然可以称为为垃圾回收器。
垃圾回收器的作用是查找和回收(清理)无用的对象。以便让JVM更有效的使用内存。
垃圾回收器的运行时间是不确定的,由JVM决定,在运行时是间歇执行的。虽然可以通过System.gc()来强制回收垃圾,但是这个命令下达后无法保证JVM会立即响应执行,但经验表明,下达命令后,会在短期内执行你的请求。JVM通常会感到内存紧缺时候去执行垃圾回收操作。
垃圾回收过于频繁会导致性能下降,过于稀疏会导致内存紧缺。这个JVM会将其控制到最好,不用程序员担心。但有些程序在短期会吃掉大量内存,而这些恐怖的对象很快使用结束了,这时候也许有必要强制下达一条垃圾回命令,这是很有必要的,以便有更多可用的物理内存。
垃圾回收器仅仅能做的是尽可能保证可用内存的使用效率,让可用内存得到高效的管理。程序员可以影响垃圾回收的执行,但不能控制。
总之,在Java语言中,判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个:
1.给对象赋予了空值null,以下再没有调用过。
2.给对象赋予了新值,既重新分配了内存空间。
7、g1回收器和其他回收器有什么区别
1
8、提高Java性能的几个高效用法
1.循环
■ 在重要的循环里,消除循环终止判断时的方法调用。。。
例如:将...
for( int i = 0; i < collection.size(); i++){
...
}
替换为…
for( int i = 0; n = collection.size(); i < n; i++){
...
}
通常,把与循环index不相关的移到循环的外面
for( int i = 0; terminal = x.length; i < terminal; i++){
X[i] = x[i] / scaleA * scaleB
}
应该该成:
Double scale = scaleb / scaleA;
for( int i = 0; terminal = x.length; i < terminal; i++){
X[i] = x[i] * scale
}
2.字符串
■ 消除字符串连接
■ 创建长字符串时,总是使用StringBuffter代替String
■ 预先分配StringBuffer空间
StringBuffer sb = new StringBuffer(5000);
3.基本数据类型
■ 在重要的循环里使用基本数据类型(int型数据通常比long/double型数据更快)
■ 基本数据类型(Boolean,Integer,etc)的包装类主要用在当传递的方法参数必须是一个对象的引用时(而不是一个基本数据类型)
■ 对所有的常量代数表达式使用static final修饰符
一 使常量更容易引用(编译器预先计算常量表达式)
4.异常
■ 异常只用于单个真正的错误条件
一 抛出一个异常和执行一个catch代码块花费是很高的(主要由于当创建一个异常时要获得线程栈的一个快照)
一 只当条件真的异常时才抛出一个异常
■ 使编译器和运行时最优化,将几个方法调用放在一个try/catch块中,而不是为每个方法调用实现几个try/catch块
try{
Some.method1(); //Difficut for javac
} catch (method1Exception e) { //and the JVM runtime
//Handle exception 1// to optimixe this code
}
try{
Some.method2();
} catch (method2Exception e) {
// Handle exception 2
}
try{
Some.method3();
} catch (method3Exception e) {
// Handle exception 3
}
try{
Some.method1();
Some.method2();
Some.method3(); // easier to optimize
} catch (method1Exception e) {
// Handle exception 1
} catch (method2Exception e) {
// Handle exception 2
} catch (method3Exception e) {
// Handle exception 3
}
5.基准
■ 注意,所有这些技巧会因不同的平台和虚拟机而不同
一 例如:在有些servlet容器内,通过一个OutputStream作为字节输出会更快
一 在其它的容器内,通过一个PrintWriter输出字符会更快
■ 这些技巧描述的是最可移植的建议
■ 你可能需要运行一些基准来判断在你的平台上怎么样是最快的
9、java虚拟机常见的几种垃圾收集算法
1、垃圾收集器概述
垃圾收集器是垃圾回收算法(标记-清除算法、复制算法、标记-整理算法、火车算法)的具体实现,不同商家、不同版本的JVM所提供的垃圾收集器可能会有很在差别,本文主要介绍HotSpot虚拟机中的垃圾收集器。
1-1、垃圾收集器组合
JDK7/8后,HotSpot虚拟机所有收集器及组合(连线),如下图:
(A)、图中展示了7种不同分代的收集器:
Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;
(B)、而它们所处区域,则表明其是属于新生代收集器还是老年代收集器:
新生代收集器:Serial、ParNew、Parallel Scavenge;
老年代收集器:Serial Old、Parallel Old、CMS;
整堆收集器:G1;
(C)、两个收集器间有连线,表明它们可以搭配使用:
Serial/Serial Old、Serial/CMS、ParNew/Serial Old、ParNew/CMS、Parallel Scavenge/Serial Old、Parallel Scavenge/Parallel Old、G1;
(D)、其中Serial Old作为CMS出现"Concurrent Mode Failure"失败的后备预案(后面介绍);
1-2、并发垃圾收集和并行垃圾收集的区别
(A)、并行(Parallel)
指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态;
如ParNew、Parallel Scavenge、Parallel Old;
(B)、并发(Concurrent)
指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行);
用户程序在继续运行,而垃圾收集程序线程运行于另一个CPU上;
如CMS、G1(也有并行);
1-3、Minor GC和Full GC的区别
(A)、Minor GC
又称新生代GC,指发生在新生代的垃圾收集动作;
因为Java对象大多是朝生夕灭,所以Minor GC非常频繁,一般回收速度也比较快;
(B)、Full GC
又称Major GC或老年代GC,指发生在老年代的GC;
出现Full GC经常会伴随至少一次的Minor GC(不是绝对,Parallel Sacvenge收集器就可以选择设置Major GC策略);
Major GC速度一般比Minor GC慢10倍以上;