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)。

分析工具:

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应用调优指南之-工具篇的更多相关文章

  1. 另一份Java应用调优指南之-前菜

    每一次成功的调优,都会诞生又一份的调优指南. 一些必须写在前面的军规,虽然与Java应用的调优没直接关联,但是测试同学经常不留神的地方. 1 独占你的测试机器 包括跑JMeter的那些机器. &quo ...

  2. Java 性能调优指南之 Java 集合概览

    [编者按]本文作者为拥有十年金融软件开发经验的 Mikhail Vorontsov,文章主要概览了所有标准 Java 集合类型.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正文: 本 ...

  3. [jvm] -- 监控和调优常用命令工具篇

    jps:java版本的ps,查看进程的信息 jps -l 输出jar包路径,类全名 jps -m 输出main参数 jps -v 输出JVM参数 jinfo:是用来查看JVM参数和动态修改部分JVM参 ...

  4. 5月29日 Java性能调优指南 读后感

    并行垃圾收集器 串行垃圾收集器 并发标记清除(CMS)垃圾收集器 Garbage First(G1)垃圾收集器 没有深入的学习G1的原理,只是看了大概的思想; SA工具:待学习

  5. 《linux性能及调优指南》 3.5 网络瓶颈

    3.5 Network bottlenecks A performance problem in the network subsystem can be the cause of many prob ...

  6. 第六章 Java性能调优工具(待续)

    Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...

  7. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  8. SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)

    前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...

  9. SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行)

    前言 上一篇我们分析了查询Hint的用法,作为调优系列的最后一个玩转模块的第一篇.有兴趣的可以点击查看:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 本篇继续玩转模块 ...

随机推荐

  1. 使用函数的递归调用来解决Hanoi(汉诺)塔问题。

    #include<stdio.h> void hanoi(int n, char x, char y, char z); void move(char x, char y); int ti ...

  2. Linux操作系统下软件的安装方法大全

    一.rpm包安装方式步骤: 1.找到相应的软件包,比如soft.version.rpm,下载到本机某个目录: 2.打开一个终端,su -成root用户: 3.cd soft.version.rpm所在 ...

  3. Castle 开发系统文章

    转: http://www.cnblogs.com/Jebel/archive/2008/06/24/1228766.html

  4. sql2008安装时提示重启计算机失败解决方法

    安装sql 2008的时候,在检测安装环境中有一项是”重新启动计算机”显示的结果是“失败”.上网看了半天,找到了解决方案,虽然我没弄明白具体原因,但问题是解决了,解决方案如下: 一.Windows+R ...

  5. 使用Flexible实现手淘H5页面的终端适配【转】

    曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时代可以跟这些麻烦说拜拜.可没想到到了移动时代,为了处理各终端的适配而乱了手脚.对于混迹各社区的偶,时常发现大家拿手机淘宝的H5页面做讨论—— ...

  6. IE插件DebugBar如何安装及使用

    DebugBar插件是一款功能很强大的IE插件,用户可以从各个不同的角度剖析Web页面内部,包括页面 详细代码.CSS样式表.所有链接.所有图片代码.脚本信息等等,不管你是编程大虾还是IT新人都和适合 ...

  7. 深入理解JVM—Java 6 JVM参数配置说明

    原文地址:http://yhjhappy234.blog.163.com/blog/static/316328322011119111014657/ 使用说明< xmlnamespace pre ...

  8. Ubuntu Geany中文乱码

    打开Geany,编辑,首选项,文件,选中“使用固定的编码打开非Unicode文件”,缺省编码选择“简体中文GBK)”. 另外,直接把文本文件拖进浏览器也行(前提是你的浏览器使用的是中文,我用的chro ...

  9. python 判断操作系统类型

    #!/bin/python # import platform def TestPlatform(): print ("----------Operation System--------- ...

  10. 87. Scramble String

    题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...