GCRootjava
全部正在运行的线程的栈上的引用变量。全部的全局变量。全部
ClassLoader。。。
1.System Class
.2.JNI Local
3.JNI Global
4.Thread Block
5.Busy Monitor
6.Java Local
7.Native Stack
8.Unfinalized
9.Unreachable
10.Java Stack Frame
11.Unknowngit
栈帧说明github
Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每一个方法被执行的时候都会同时建立一个栈帧(Stack Frame)用于存储局部变量表、操做栈、动态连接、方法出口等信息。每个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。浏览器
方法区说明服务器
与Java堆同样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。并发
常规优化函数
一、禁用System.gc
二、逃逸分析与标题替换
三、关闭偏向锁优化
四、指针压缩
五、getter方法优化工具
参数设置性能
一、-XX:-DisableExplicitGC,禁用了System.gc()的显示调用
二、逃逸分析默认是启用的,-XX:+DoEscapeAnalysis。后续有三种优化会进行:栈内分配,同步消除,标量替换
四、偏向锁,关闭: -XX:-UseBiasedLocking-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0
五、指针压缩,-XX:+UseCompressedOops
六、getter方法优化,-XX:UseFastAccessorMethods测试
解释
分析对象动态做用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如做为调用参数传递到其余方法中,称为方法逃逸。 甚至还有可能被外部线程访问到,譬如赋值给类变量或能够在其余线程中访问的实例变量,称为线程逃逸。
栈上分配(Stack Allocation ):若是肯定一个对象不会逃逸出方法以外,那让这个对象在栈上分配内存将会是一个很不错的主意。因为HotSpot 虚拟机目前的实现方式致使栈上分配实现起来比较复杂,所以在HotSpot 中暂时尚未作这项优化 。
同步消除(Synchronization Elimination ):线程同步自己是一个相对耗时的过程,若是逃逸分析能
够肯定一个变量不会逃逸出线程,没法被其余线程访问,那这个变量的读写确定就不会有竞争,对
这个变量实施的同步措施也就能够消除掉 。
标量替换(Scalar Replacement ):标量(Scalar )是指一个数据已经没法再分解成更小的数据来表示了,Java 虚拟机中的原始数据类型(int 、 long 等数值类型以及reference 类型等)都不能再进一步分解,它们就能够称为标量。 相对的,若是一个数据能够继续分解,那它就称做聚合量(Aggregate ),Java 中的对象就是最典型的聚合量。 若是把一个Java 对象拆散,根据程序访问的状况,将其使用到的成员变量恢复原始类型来访问就叫作标量替换。 若是逃逸分析证实一个对象不会被外部访问,而且这个对象能够被拆散的话,那程序真正执行的时候将可能不建立这个对象,而改成直接建立它的若干个被这个方法使用到的成员变量来代替 。
JIT优化
一、开启服务端模式
二、增长内联函数的可能性
三、提升编译的可能性
四、下降线程优先级
五、热度衰减与半衰周期
参数
一、服务端模式,-server
二、final的函数是向编译器建议能够内联,启动参数不宜设置
三、提升编译的可能性,小方法,-XX:CompileThreshold=10000
四、线程优先级,Linux不能设置,须要root权限
五、热度衰减与半衰周期
解释
OSR编译阈值
A、调用计数器,即方法被调用的次数,CompileThreshold,该值是指当方法被调用多少次后,就编译为机器码,client模式默认为1500次,server模式默认为1万次,能够在启动时添加-XX:CompileThreshold=10000来设置该值。
B、回边计数器,即方法中循环执行部分代码的执行次数,OnStackReplacePercentage,该值用于/参与计算是否触发OSR编译的阈值,client默认为933,sever默认为140,能够经过-XX:OnStackReplacePercentage=140来设置。
client模式下的计算规则为CompileThreshold*OnStackReplacePercentage/100,server模式下计算规则为
CompileThreshold*(OnStackReplacePercentage-InterpreterProfilePercentage)/100。InterpreterProfilePercentage,默认为33。
思路
一、将新对象预留在年轻代
二、让大对象进入年老代
三、设置对象进入年老代的年龄
四、稳定的 Java 堆
五、增大吞吐量提高系统性能
六、使用非占有的垃圾回收器
参数
一、将新对象预留在年轻代,-XX:TargetSurvivorRatio=90
二、让大对象进入年老代,-XX:PetenureSizeThreshold=1000000,1M
三、设置对象进入年老代的年龄,-XX:MaxTenuringThreshold=31
四、稳定的 Java 堆 ,Xmx与Xms相同
5 、 增 大 吞 吐 量 提 升 系 统 性 能 , – X X : + U s e P a r a l l e l G C ,–XX:+UseParallelOldGC,–XX:ParallelGC-Threads(CPU核心数相等)
六、使用非占有的垃圾回收器,–XX:+UseConcMarkSweepGC
工具
jps:虚拟机进程情况工具
它的功能也和ps命令相似:能够列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机惟一ID(Local Virtual Machine Identifier,LVMID)。jps能够经过RMI协议查询开启了RMI服务的远程虚拟机进程状态,hostid为RMI注册表中注册的主机名。
jstat:虚拟机统计信息监视工具
用于监视虚拟机各类运行状态信息的命令行工具。它能够显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
jmap:Java内存映像工具
map的做用并不只仅是为了获取dump文件,它还能够查询finalize执行队列、Java堆和永久代的详细信息,如空间使用率、当前用的是哪一种收集器等。
其余工具
jinfo:Java配置信息工具做用是实时地查看和调整虚拟机各项参数。使用-sysprops选项把虚拟机进程System.getProperties()的内容打印出来。
jhat:虚拟机堆转储快照分析工具jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,能够在浏览器中查看。
HSDIS:JIT生成代码反汇编HSDIS是一个HotSpot虚拟机JIT编译代码的反汇编插件,它包含在HotSpot虚拟机的源码之中,但没有提供编译后的程序。
可视化工具
JConsole:Java监视与管理控制台JConsole(Java Monitoring and Management Console)是一种基于JMX的可视化监视、管理工具。它管理部分的功能是针对JMX MBean进行管理,因为MBean可使用代码、中间件服务器的管理控制台或者全部符合JMX规范的软件进行访问。
VisualVM:多合一故障处理工具VisualVM(All-in-One Java Troubleshooting Tool)是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序。VisualVM的还有一个很大的优势:不须要被监视的程序基于特殊Agent运行,所以它对应用程序的实际性能的影响很小,使得它能够直接应用在生产环境。
JMC:Oracle Java Mission Control 是一个用于对 Java 应用程序进行管理、监视、概要分析和故障排除的工具套件。首次安装时,Java Mission Control 包括 JMX 控制台和 Java 飞行记录器。从 Mission Control 中能够轻松安装更多插件
JITWatch
安装:
git clone git@github.com:AdoptOpenJDK/jitwatch.git cd jitwatch mvn clean install -DskipTests=true
运行:launchUI.bat
使用:XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly
查看结果。
服务器:8 cup, 8G mem
e.g.
java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0
调优方案:
-Xmx5g:设置JVM最大可用内存为5G。
-Xms5g:设置JVM初始内存为5G。此值能够设置与-Xmx相同,以免每次垃圾回收完成后JVM从新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆内存大小 = 年轻代大小 + 年老代大小 + 持久代大小 。持久代通常固定大小为64m,因此增大年轻代后,将会减少年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,因此无需再设置此值。
-XX:ParallelGCThreads=8:配置并行收集器的线程数,即:同时多少个线程一块儿进行垃圾回收。此值最好配置与处理器数目相等。
-XX:SurvivorRatio=6:设置年轻代中Eden区与Survivor区的大小比值。根据经验设置为6,则两个Survivor区与一个Eden区的比值为2:6,一个Survivor区占整个年轻代的1/8。
-XX:MaxTenuringThreshold=30: 设置垃圾最大年龄(次数)。若是设置为0的话,则年轻代对象不通过Survivor区直接进入年老代。对于年老代比较多的应用,能够提升效率。若是将此值 设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活时间,增长在年轻代即被回收的几率。设置为30表示 一个对象若是在Survivor空间移动30次尚未被回收就放入年老代。
-XX:+UseConcMarkSweepGC:设置年老代为并发收集。测试配置这个参数之后,参数-XX:NewRatio=4就失效了,因此,此时年轻代 大小最好用-Xmn设置,所以这个参数不建议使用。