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. 【技术贴】解决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 ...

  2. DelayedOperationPurgatory之DelayedOperation pool

    purgatory就是炼狱的意思. 当一个DelayedOperation需要被delay时,它就被放到DelayedOperationPurgatory,相当于进行一个等待池.上一篇blog提到过, ...

  3. 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 ...

  4. struts2-2.3.4.1的struts-default.xml源码

    <?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id: struts-default.x ...

  5. intellij idea 12、13 win8 下 中文输入覆盖的问题(搜狗输入法或者其他输入法)

    最近升级到idea12,发现中文输入存在问题,输入中文的时候会出现空格,并且覆盖后面的字符,这个问题让我很郁闷. 假设idea的安装位置为:D:\Program Files\JetBrains\Int ...

  6. mysql 多表 update sql语句总结

    mysql 多表 update 有几种不同的写法. 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是ProductPrice表,我们要将ProductP ...

  7. asp.net后台获取路径的各种方法归纳

    asp.net后台获取路径的各种方法归纳   1.Request.CurrentExecutionFilePath    获取当前请求的虚拟路径,不同于 FilePath,差别在于如果请求已在服务器代 ...

  8. 李洪强iOS开发之OC[013] -类的创建的练习

    // //  main.m //  12 - 类的创建练习 // //  Created by vic fan on 16/7/9. //  Copyright © 2016年 李洪强. All ri ...

  9. 【Linux高频命令专题(16)】less

    概述 less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向 ...

  10. Android 线程通讯类Handler

    handler是线程通讯工具类.用于传递消息.它有两个队列: 1.消息队列 2.线程队列 消息队列使用sendMessage和HandleMessage的组合来发送和处理消息. 线程队列类似一段代码, ...