Java应用调优指南之-工具篇
1. 土法调优两大件
先忆苦思甜,一般人在没有Profile工具的时候,调优的两大件,无非Heap Dump 与 Thread Dump。
1.1 Heap Dump
jmap -dump:live,format=b,file=heap.hprof pid
从安全点的日志看,从Heap Dump开始,整个JVM都是停顿的,考虑到IO(写到Page Cache,或许触发background flush),几G的Heap可能产生几秒的停顿,在生产环境上执行时谨慎再谨慎。
live的选项,实际上是产生一次Full GC来保证只看还存活的对象。有时候也会故意不加live选项,看历史对象。
Dump出来的文件建议用JDK自带的VisualVM或Eclipse的MAT插件打开,对象的大小有两种统计方式:
- 本身大小(Shallow Size):对象本来的大小。
- 保留大小(Retained Size): 当前对象大小 + 当前对象直接或间接引用到的对象的大小总和。
看本身大小时,占大头的都是char[] ,byte[]之类的,没什么意思(用jmap -histo:live pid 看的也是本身大小)。所以需要关心的是保留大小比较大的对象,看谁在引用这些char[], byte[]。
(MAT能看的信息更多,但VisualVM胜在JVM自带,用法如下:命令行输入jvisualvm,文件->装入->堆Dump->检查 -> 查找20保留大小最大的对象,就会触发保留大小的计算,然后就可以类视图里浏览,按保留大小排序了)
1.2 Thread Dump
ThreadDump 同样会造成JVM停顿,在生产系统上执行要谨慎。
可以命令行方式执行它,"jstack pid” 或"jstack -l pid" ,其中-l 会同时打印各种lock,但会使得JVM停顿得长久得多(可能会差一百倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),慎用再慎用。
另一种是直接用代码来打印,比如线程池满了无法添加新任务,在开发或性能测试模式下,可以在代码里捕捉该异常后直接把当前线程池的情况打印出来。
ThreadMXBean threadMBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMBean.dumpAllThreads(false, false);
同样注意,这里threadMBean.dumpAllThreads(false,false)的参数为false,把参数改为true,则打印synchronizers与monitor,同样使得JVM停顿久很多。
线程状态:
- RUNNABLE: 运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。
- BLOCKED:被某个锁(synchronizers)給block住了。
- WAITING:等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。
- TIME_WAITING:和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。
分析工具:
- IBM Thread and Monitor Dump Analyze for Java 一个小巧的Jar包,能方便的按状态,线程名称,线程停留的函数排序,快速浏览。
- http://spotify.github.io/threaddump-analyzer Spotify提供的Web版在线分析工具,可以将锁或条件相关联的线程聚合到一起。
2. 你真正要的Java Mission Control
如果你使用过JProfiler,Yourkit,VisualVM还有Eclipse的Profiler插件等一堆Profiler工具,或者用JavaSimion等在代码里打印过metrics,最后会发现免费的JMC才是你想要的。
2.1 优点
代替收费的JProfiler的好东西,以前Bea JRockit的宝贝,现在随着JDK7 up40以后的版本免费自带了,不过只在开发环境免费,就是说理论上不能拿它来连生产环境的机器。
另一个让人开心的事情就是JMC采用采样,而不是传统的代码植入的技术,对应用性能的影响非常非常小,完全可以开着JMC来做压测。不会像以前,开了代码植入型的Profiler,出来的性能测试结果差了一个数量级不说,热点完全可能是错误的,这是一个真实的故事,具体细节就不说了。
2.2 功能
JMC里可以看的东西太多了,自己觉得最有用的如下:
- 内存Tab:分配Tab里的按类、按线程、对象的创建调用栈来归类的对象创建情况,让对象创建无处躲藏。
- 内存Tab:GC Tab的GC详细情况,以及分配Tab中TLAB外的分配情况(每条线程在Heap里分了一个Thread Local Area,在TLAB里的内存分配不需要线程竞争,所以TLAB之外的分配是不好的)
- 代码Tab:热点方法类及它的调用栈,超有用的功能。调用树是从线程角度看的方法调用,而按包名分类可以看3PP包的问题。
- 线程Tab:热点线程,再换个姿势来看热点方法和调用树。
- 线程Tab:争用,等待时间,锁定实例等。
2.3 使用方法简述
JDK7在启动服务时加上-XX:+UnlockCommercialFeatures -XX:+FlightRecorder ,JDK8则不需要。
如果是远程服务器,要开JMX:
“-Dcom.sun.management.jmxremote.port=7001 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1”
JDK自带的jmc命令,文件->连接->设定JMX连接,启动飞行纪录,固定时间选1分钟或更多,事件设置选为profiling,然后进一步修改,自己查看下都Profile了哪些信息,觉得不够的再添加些(下次就直接用上次设定就好了),比如:
- 加上对象数量的统计:Java Virtual Machine->GC->Detail->Object Count/Object Count after GC
- 方法调用采样的间隔从10ms改为1ms(但不能低于1ms,否则会影响性能了): Java Virtual Machine->Profiling下的两个选项
- Socket与File采样的间隔从10ms改为1ms(默认的10ms会捕捉不到IO): Java Application->File Read/FileWrite/Socket Read/Socket Write
然后就开始Profile,到时间后Profile结束,会自动把记录下载回来,在JMC中展示。
其他资料:
Java应用调优指南之-工具篇的更多相关文章
- 另一份Java应用调优指南之-前菜
每一次成功的调优,都会诞生又一份的调优指南. 一些必须写在前面的军规,虽然与Java应用的调优没直接关联,但是测试同学经常不留神的地方. 1 独占你的测试机器 包括跑JMeter的那些机器. &quo ...
- Java 性能调优指南之 Java 集合概览
[编者按]本文作者为拥有十年金融软件开发经验的 Mikhail Vorontsov,文章主要概览了所有标准 Java 集合类型.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文: 本 ...
- [jvm] -- 监控和调优常用命令工具篇
jps:java版本的ps,查看进程的信息 jps -l 输出jar包路径,类全名 jps -m 输出main参数 jps -v 输出JVM参数 jinfo:是用来查看JVM参数和动态修改部分JVM参 ...
- 5月29日 Java性能调优指南 读后感
并行垃圾收集器 串行垃圾收集器 并发标记清除(CMS)垃圾收集器 Garbage First(G1)垃圾收集器 没有深入的学习G1的原理,只是看了大概的思想; SA工具:待学习
- 《linux性能及调优指南》 3.5 网络瓶颈
3.5 Network bottlenecks A performance problem in the network subsystem can be the cause of many prob ...
- 第六章 Java性能调优工具(待续)
Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...
- Java多线程编程实战指南(核心篇)读书笔记(五)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)
前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...
- SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行)
前言 上一篇我们分析了查询Hint的用法,作为调优系列的最后一个玩转模块的第一篇.有兴趣的可以点击查看:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 本篇继续玩转模块 ...
随机推荐
- 【技术贴】解决MySql连接不上 ip远程连接Host is not allowed to conn
落雨 如果你想连接远程IP的mysql的时候发生这个错误: ERROR 1130: Host '192.168.1.3' is not allowed to connect to this MySQL ...
- DelayedOperationPurgatory之DelayedOperation pool
purgatory就是炼狱的意思. 当一个DelayedOperation需要被delay时,它就被放到DelayedOperationPurgatory,相当于进行一个等待池.上一篇blog提到过, ...
- How to define Servlet filter order of execution using annotations
If we define Servlet filters in web.xml, then the order of execution of the filters will be the same ...
- struts2-2.3.4.1的struts-default.xml源码
<?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id: struts-default.x ...
- intellij idea 12、13 win8 下 中文输入覆盖的问题(搜狗输入法或者其他输入法)
最近升级到idea12,发现中文输入存在问题,输入中文的时候会出现空格,并且覆盖后面的字符,这个问题让我很郁闷. 假设idea的安装位置为:D:\Program Files\JetBrains\Int ...
- mysql 多表 update sql语句总结
mysql 多表 update 有几种不同的写法. 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是ProductPrice表,我们要将ProductP ...
- asp.net后台获取路径的各种方法归纳
asp.net后台获取路径的各种方法归纳 1.Request.CurrentExecutionFilePath 获取当前请求的虚拟路径,不同于 FilePath,差别在于如果请求已在服务器代 ...
- 李洪强iOS开发之OC[013] -类的创建的练习
// // main.m // 12 - 类的创建练习 // // Created by vic fan on 16/7/9. // Copyright © 2016年 李洪强. All ri ...
- 【Linux高频命令专题(16)】less
概述 less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向 ...
- Android 线程通讯类Handler
handler是线程通讯工具类.用于传递消息.它有两个队列: 1.消息队列 2.线程队列 消息队列使用sendMessage和HandleMessage的组合来发送和处理消息. 线程队列类似一段代码, ...