JVM学习笔记(四)

版权声明:欢迎转载,转载请注明原博客网址 https://blog.csdn.net/qq_37497322/article/details/82755790

(7)G1收集器
G1收集器是当今收集器技术发展最前沿的成果之一,它被视为JDK1.7中HotSpot虚拟机的一个重要进化特征。G1是一款面向服务端应用的垃圾收集器,HotSpot开发团队赋予它的使命是替换掉CMS收集器,它的特点有:
1)并行与并发:G1能充分利用CPU,多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World停顿时间,部分其
他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以并发的方式让Java程序继续运行。
2)分代收集:与其他收集器一样,分代概念在G1中依然得以保留。虽然G1可以不需要其他收集器配合就能独立管理整个
GC堆,但它能采用不同的方式去处理新创建的对象和已经存活一段时间,熬过多次GC的旧对象以获得更好的收集效果。
3)空间整合:与CMS"标记-清理"算法法不同,G1从整体上来看是基于"标记-整理"算法实现的收集器,从局部(两个
region)来看是基于复制算法实现的,但无论如何,这两种算法都意味着在G1运作期间不会产生内存空间碎片,收集后
能提供规整可用的内存,这种特性有利于程序长时间运行,分配大对象时不会因为无法找到连续内存空间而提前触发下一次GC。
4)可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)垃圾收集器的特征了。
在G1之前的其他收集器收集的范围都是整个新生代或者老年代,而G1不同。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(region),此时新生代和老年代不再是物理隔
离的了,它们都是一部分Region(不需要连续)的集合。
因为G1收集器可用有计划地避免在整个Java堆中进行全区域的垃圾收集,所以能建立可预测停顿时间的模型。G1跟踪各个Region里的垃圾堆的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次
根据允许的收集时间,优先回收价值最大的Region(Garbage-First名称的由来。这种使用Region划分内存空间
以及有优先级的区域回收方式,保证了GF收集器在有限的时间内可以获取尽可能高的收集效率。
G1收集器中,Region之间的对象引用以及其他收集器中新生代和老年代之间的对象引用,虚拟机都是使用Remember Set来避免全堆扫描的。G1中每个Region都有一个与之对应的Remember Set,虚拟机发现程序在对Reference类型
数据进行写操作时,会产生一个Write Barrier暂时中断写操作,检查Reference引用的对象是否处于不同的
Region之中,如果是,便通过CardTable把相关引用信息记录到被引用对象所属的Region的Remember Set中,
当进行内存回收时,在GC根节点的枚举范围中加入RememberSet即可保证不对全堆扫描也不会有遗漏。
如果不计算维护RememberSet的操作,G1收集器运作大致可划分为初始标记,并发标记,最终标记,筛选回收。初始标记阶段仅仅是标记一下GC Roots能直接关联到的对象,并且只修改TAMS(Next Top at Mark Start)的值,让下一
阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程,但耗时很短。并发标记阶段是从GC Root开始堆堆对象进行可达性分析,找出存活的对象,这阶段耗时长,但和与用户程序并发执行,最终标记阶段
是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remember Set中,虚拟机将这段时间对象变化记录在线程Remember Set Logs里面,最终标记阶段需要把
Remember Set Logs的数据合并到RememberSet中,这阶段需要停顿线程,但是是可并行执行。最后在筛选回收
阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。
21.内存分配与回收策略
对象内存的分配,就是在堆上分配,对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机与内存相关的参数的设置。
(1)对象优先在Eden分配
大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。
新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因Java对象大多都具备朝生夕灭的特性,所以Minor GC
非常频繁,一般回收速度也比较快
老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对)。Major GC的速度一般会比Minor GC慢10倍以上。
(2)大对象直接进入老年代
大对象是指需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组。大对象对内存分配来说是一个坏消息,经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够连续的空间来"安置"它们。虚拟机提供了一个参数,令大于这个设置值的对象直接在老年代分配,这样做的目的是避免Eden及两个Survivor
区之间发生大量的内存复制。
(3)长期存活的对象将进入老年代
虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且
能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor区中每"熬过"一次
Minor GC,年龄就增加一岁,当它的年龄到一定程度(默认为15岁),就将会被晋升到老年代中,这个默认值可通过参数设置。
(4)动态对象年龄判定
为了更好地适应不用程序的内存状况,虚拟机并不是永远地要求对象年龄必须达到设置值才能晋升老年代,如果在
Survivor空间中相同年龄有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可直接进入老年代。
(5)空间分配担保
在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间,如果这个条件
成立,那么Minor GC可用确保是安全的。如果不成立,虚拟机会查看设置的值是否允许担保失败。如果允许,那么会
继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor
GC,尽管这次Minor GC是有风险的,如果小于,或者参数设置是不允许冒险的,那这时要改为进行一次Full GC。
22.Sun JDK监控和故障处理工具
在JDK的bin目录中,有用于监视虚拟机和故障处理的工具。
jps:显示指定系统内所有HotSpot虚拟机进程
jstat:用于收集HotSpot虚拟机各方面的运行数据
jinfo:显示虚拟机配置信息
jmap:生成虚拟机的内存转储快照(heapdump文件)
jhat:用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果
jstack:显示虚拟机的线程快照
23.jps:虚拟机进程状况工具
JDK很多工具的名字都参考了UNIX命令的命名方式,jps除了名字像UNIX的命令ps外,它的功能也类似,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一的ID。虽然功能单一,但它是使用频率最高的JDK命令行工具,因为其他JDK工具都需要它查询到LVMID来确定要监控的是哪一个虚拟机进程。对于本地虚拟机进程来说,LVMID与操作系统的进程ID是一致的,使用Windows的任务管理器和UNIX的ps命令也可以查询到虚拟机进程的LVMID,如果同时启动了多个虚拟机进程,无法根据进程名称定位时,那就只能依赖jps命令显示主类的功能才能区
分了。
jps命令格式:
jps [options] [hostid]
jps可以通过RMI协议查询开启了RMI服务的远程虚拟机进程状态,hostid为RMI注册表中的注册的主机名。
jps其他常用的选项:
-q:只输出LVMID,省略主类的名称
-m:输出虚拟机进程启动时传递给主类main()函数的参数
-l:输出主类的全名,如果进程执行的是jar包,输出jar包的路径
-v:输出虚拟机进程启动时JVM参数
24.jstat:虚拟机统计信息监视工具
jstat是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载,内存,垃圾收集,JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能的首选工具
jstat命令格式:
jstat [option vmid[interval][s|ms] [count]]
如果是本地虚拟机进程,VMID和LMID是一致的,如果是远程虚拟机进程,那么VMID的格式应当是:
[protocol:][//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次,如果要每250ms查询一次进程2764垃圾收集情况,一共查询20此,那么命令应该是:
jstat -gc 2764 20
选项option代表着用户希望查询的虚拟机信息,主要分为3类:类装载,垃圾收集,运行期编译状况。
jstat主要选项:
-class:监视类装载,卸载数量,总空间以及类装载所耗费的时间
-gc:监视Java堆状况,包括Eden区,另个Survivor区,老年代,永久代的容量,已用空间,GC时间合计等信息。
-gccapacity:监视内容基本与-gc相同,但主要输出Java各个区域使用到的最大,最小空间
-gcutil:监视内容基本与-gc相同,但主要输出已使用空间占总空间的百分比
-gccause:与gcutil功能一样,但会额外输出导致上一次GC产生的原因
-gcnew:监视新生代GC状况
-gcnewcapacity:监视内容与-gcnew基本相同,但输出主要为使用到的最大,最小空间
-gcold:监视老年代GC状况
-gcoldcapacity:视内容与-gcold基本相同,但输出主要为使用到的最大,最小空间
-gcpermcapacity:输出永久代使用到的最大,最小空间
-compiler:输出JIT编译器编译过的方法,耗时等信息
-printcompilation:输出已经被JIT编译的方法
25.jinfo:java配置信息工具
jinfo的作用是实时地查看和调整虚拟机各项参数,使用jps的-v参数就可以查看虚拟机启动显示指定的参数列表,但如果想知道未被显式指定的参数的系统默认值,出去找资料外,就只能使用jinfo的-flag选项进行查询了,jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()的内容打印出来。
jinfo命令格式:
jinfo [option] pid
26.jmap:java内存映像工具
jmap命令用于生成堆转储快照。如果不使用jmap命令,想要获取Java堆转储快照,要有一些比较"暴力的手段",如添加参数,可以让虚拟机在OOM异常之后自动生成dump文件,还有参数可以使用按键让虚拟机产生dump文件,或者在inux中通过kill -3命令发送进程退出信号"吓唬"虚拟机也能拿到dump文件。
jmap的作用不仅仅是为了获取dump文件,还可以查询finalize执行队列,Java堆和永久代的详细信息,如空间使用率,当前是哪种收集器等。和jinfo命令一样,jmap有很多功能在windows下都是受限的,除了生成dump文件的-dump和用于查看每个类的实例,空间占用统计的-histo选项在所有的操作系统都提供之外,其余的选项只能在Linux/Solaris下使用。
jmap命令格式:
jmap [ option ] vmid
选项:
-dump:生成java堆转存储快照,格式:-dump:[live,]format=b,file=<filename>,其中live子参数说明是否
只dump出存活的对象。
-finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象。
-heap:显示java堆详细信息,如使用那种回收器,参数配置,分代状况等。
-histo:显示堆中对象统计信息,包括类,实例数量,合计容量。
-permstat:以ClassLoader为统计口径显示永久代内存状态。
-F:当虚拟机进程对-dump选项没有响应时,可使用这个参数强制生成dump快照。
LVMID是通过jps命令查询到的。
27.jhat:虚拟机堆转快照分析工具
Sun JDK提供jhat命令和jmap搭配使用,来分析jmap生成的堆转储快照。jhat内置了一个微型的HTTP/HTML服务
器,生成dump文件的分析结果后,可以在浏览器中查看。在实际工作中,除非手中真的没什么别的工具,否则一般不会直接使用jhat命令来分析dump文件,即使可以这样做,最好也将dump文件复制到其他机器上进行,因为分析工作是一个耗时而且消耗硬件资源的过程,另一个原因是jhat分析功能相对来说比较简陋,像一些专用于分析dump文件的工具,
Eclipse Memory Analyzer,IBM HeapAnalyzer等工具都实现了比jhat更强大更专业的分析功能。
28.jstack:Java堆栈跟踪工具
jstack命令用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁,死循环,请求外部资源导致的长时间等待等都是定位线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待什么资源。
jstack命令格式:
jstack [ option ] vmid
option选项:
-F:当正常输出的请求不被响应时,强制输出线程堆栈。
-l:除堆栈外,显示关于锁的附加信息。
-m:如果调用到本地方法的话,可用显示c/c++的堆栈。
29.HSDIS:JIT生成代码反汇编
HSDIS是一个Sun官方推荐的HotSpot虚拟机JIT编译代码的反汇编插件,它包含在HotSpot的源码之中,但没有提供编译后的程序。在Project Kenai的网站也可用下到单独的源码。它的作用是让HotSpot的-XX:+PrintAssembly
指令调用它来把动态生成的本地代码还原为汇编代码输出,同时还生成大量非常有价值的注释,这样就可以通过输出的代码来分析问题。
30.JDK可视化工具
JDK中除了大量的命令行工具外,还有两个功能强大的可视化工具,Jconsole和VisualVM,其中JConsole是在JDK1.5时期就已经提供的虚拟机监控工具,而VisualVM在DJK1.6中才首次发布,现在已经成为Sun主力推动的多合一故障处理工具,并且已经从JDK中分离出来成为可用独立发展的开源项目。
(1)JConsole:Java监视与管理控制台
JConsole是一种基于JMX的可视化监视,管理工具。它管理功能是针对JMX MBean进行管理,MBean
可用使用代码,中间件服务器的管理控制台或者所有符合JMX规范的软件进行访问。
JConsole监视部分的功能:
1)启动JConsole
通过JDK/bin目录下的"jconsole.exe"启动JConsole后,将自动搜索出本机运行的所有虚拟机进程,不需要
用户自己再通过jps来查询了。主界面包括"概述","内存","线程","类","VM摘要","MBean"6个页签。"概述"
页签显示的是整个虚拟机主要运行数据的概览,其中包括"堆内存使用情况","线程","类","CPU使用情况"四种信息的曲线。
2)内存监控
"内存"页签相当于可视化的jstat命令,用于监视受收集器管理的虚拟内存(Java堆和永久代)的变化趋势。程序运行后
在"内存"页签中可用看到本地内存池Eden区的运行趋势。
3)线程监控
“线程”页签相当于可视化的jstack命令,遇到线程停顿时可用使用这个页签进行监控分析。
(2)VisualVM:多合一故障处理工具
VisualVM是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序,它除了运行监视,故障处理外,还提供了很多其他方面的功能。如性能分析,VisualVM的性能分析功能甚至就比起JProfiler,YourKit等专业的Profiling工具都不会逊色多少,而且VisualVM还有一个很大的优点:不需要被监视的程序基于特殊Agent运行,因此它对应用程序的实际性能影响很小。
1)VisualVM兼容范围与插件安装
VisualVM基于NetBeans平台开发,因此它一开始就具备了插件扩功能的特性,通过插件扩展支持,它可用做到:
显示虚拟机进程以及进程的配置,环境信息
监视应用程序的CPU,GC,堆,方法区以及线程的信息
dump以及分析堆转出快照
方法级的程序运行性能分析,找出被调最多,运行时间最长的方法
离线程序快照,收集程序运行时配置,线程dump,内存dump等信息建立一个快照
首次启动VisualVM后,不必着急找应用程序进行监测,因为VisualVM还没加载任何插件,没有装任何插件,相当于放弃了它最精华的功能。
2)生成,浏览转存储快照
在VisualVM中,生成dump有以下两种方式:
在"应用程序"窗口中右键单击应用程序节点,然后选择"堆 Dump"
在"应用程序"窗口中双击应用程序节点以打开应用程序标签,然后在"监视"标签中单击"Dump"
3)分析程序性能
在Profiler页签中,VisualVM提供了程序运行期间方法级的CPU执行时间分析以及内存分析,做Profiler分析肯定会对程序运行性能有比较大的影响,所以一般不在生产环境中使用这项功能。
要开始分析,先选择"CPU"和"内存"中的一个,然后切换到应用程序中对程序进行操作,VisualVM会记录这段时间中应用程序执行过的方法。如果是CPU分析,将会统计每个方法的执行次数,执行耗时;如果是内存分析,则会统计每个方法关联的对象以及这些对象所占的空间。
4)BTrace动态日志跟踪
BTrace是一个很有趣的插件,本身也是一个可用独立运行的程序,他的作用是在不停止目标程序的前提下,通过HotSpot虚拟机的HotSwap技术动态加入原本不存在的动态调试代码。BTrace的用法还很多,打印调用堆栈,参数,返回值是最基本的应用,在它的网站上有使用BTrace进行性能监视,定位连接内存泄漏,解决多线程竞争问题等例子。
 

猜你喜欢

转载自blog.csdn.net/qq_37497322/article/details/82755790