【软件构造】课件精译(二十) 动态性能分析方法与工具

一、动态程序分析

动态程序分析:根据程序的一次或多次执行的过程与结果,分析代码在时空性能方面所展现出的性质
静态与动态分析
【软件构造】课件精译(二十) 动态性能分析方法与工具
为使动态分析有效,目标程序必须执行足够多次,以观察到完整的、不同的执行行为。
通过分析代码覆盖度,确认动态分析是否已经足够。
要尽可能小的影响程序原本的执行,否则性能测量不准确 。
测量某事物的行为将会不可避免的干扰/扰乱它,从而改变它的状态。
Example 1:程序热点
每个程序实体(语句、分支、路径、方法等)的执行概率/频度是多少?
80-20原则:20%的程序负责80%的执行时间
目标:性能调优、性能分析驱动的编译、****
Example 2:路径分析
【软件构造】课件精译(二十) 动态性能分析方法与工具

二、程序剖析:概念和方法

剖析器
利用剖析器检测源代码或执行程序以获取信息,用于代码过于庞大而难以阅读剖析的情况
这个工具可以用来评估代码在新架构上的表现,发现代码的关键区域以及指令调度或分支预测算法的执行情况
剖析器的输出
所观察到的程序执行事件的统计结果,同代码量相关
【软件构造】课件精译(二十) 动态性能分析方法与工具
输出一个事件流,事件跟踪同指令路径长度相关
【软件构造】课件精译(二十) 动态性能分析方法与工具
实时或周期性的获取/展示程序运行过程中的数据,提供了在执行期间在任何期望的点处开启或关闭trace的机会,提供了在关键点暂停异步进程以更详细地检查与其他并行进程的交互
【软件构造】课件精译(二十) 动态性能分析方法与工具
平面剖析器根据调用计算平均调用时间,并且不根据被调用者或上下文分解调用时间。
调用图剖析器显示调用时间,功能的频率,以及基于被调用者所涉及的调用链。 在某些工具中,不保留完整的上下文。
输入敏感性剖析通过将性能度量与输入工作负载的功能相关联(例如输入大小或输入值),为平面或调用图剖析器添加更多维度。 它们生成的图表表征应用程序的性能如何根据其输入进行扩展。
剖析方法
剖析器可以使用许多不同的技术,例如基于事件的,统计的,仪表化的和模拟的方法。在收集数据方面,剖析器采用硬件中断、代码指令、指令集模拟、操作系统挂钩、性能计数器
剖析器通常采用以下三种方法:

(1)代码注入/代码插入

在原始程序中加入某些语句来收集运行时数据,这些语句不改变原程序的语义,但对原程序的性能有了轻微改变
在源代码中注入较为简单,在目标代码(.o与.class)中较为困难

Pros:可以被很多平台使用,在某些意义上比较准确,无法比较容易地做内存剖析
Cons:需要修改程序;注入代码可能影响测试结果

(2)采样

以特定的频率观察程序执行在特定时刻所展现出的行为与状态
采样:周期性监控被测程序,存储各时刻的快照
基于收集到的数据,分析程序当时所处的状态,分析性能

Pros:不需要修复程序
Cons:需要在采样频率和准确度之间折中;可能漏掉“小”的方法;难以监控内存使用情况

(3)借助于虚拟机获取程序性能数据

利用虚拟机进行性能监控,所有JVM执行的指令都被记录下来

Pros: 非常准确,可监控时空两方面的性能
Cons: 与VM绑定,不同VM需要提供不同的测量工具

三、程序剖析工具

(1)命令行剖析工具

jstat:获取JVM的heap使用和GC的性能统计数据
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
jmap:输出内存中的对象分布情况
jmap -dump:format=b,file=filename causes jmap to dump the Java heap in binary format to a specified file. 导出heap dump

jmap -histo for obtaining a class specific histogram(柱状图) of the heap. 获取堆中类的特定柱状图
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
jhat:导出heap dump,浏览/查询其中的对象分布情况
jhat是heap dump文件的浏览和查询工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
OQL(Object Query Language)
【软件构造】课件精译(二十) 动态性能分析方法与工具

jstack:获取Java线程的stack trace
【软件构造】课件精译(二十) 动态性能分析方法与工具
jstack为给定的Java进程或核心文件或远程调试服务器打印Java线程的堆栈跟踪
主要用途:
定位线程出现长时间停顿的原因,如多线程间死锁、死循环、请求外部资源导致的长时间等待等。
线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
【软件构造】课件精译(二十) 动态性能分析方法与工具
jps (JVM Process Status Tool) 虚拟机进程状况工具: 列出当前运行的JVM 进程

jMC:Java Mission Control是一个剖析、检测和诊断的工具集

(2)JConsole

JConsole图形用户界面是一个监视工具,提供有关Java平台上运行的应用程序的性能和资源消耗的信息。
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具

(3)VisualVM

VisualVM是一个工具,它提供了一个可视化界面,用于在JVM上运行时查看有关Java应用程序的详细信息
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
Visual GC
【软件构造】课件精译(二十) 动态性能分析方法与工具

四、内存分析器(MAT)

Eclipse Memory Analyzer是一个快速且功能丰富的Java堆分析,可帮助您查找内存泄漏并减少内存消耗。——内存堆导出文件的分析工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
浅堆和保留的堆
浅堆:某个对象消耗的实际内存
保留的堆:如果某对象被GC,所释放的内存
对象的浅堆是其在堆中的大小,而保留的大小是在对象被垃圾回收时将释放的堆内存量。
Outgoing references:该对象所引用的其他对象
Incoming references:引用该对象的其他对象
Group by class loader, packages or superclass
支配树:支配树展示了内存导出文件中最大的对象
【软件构造】课件精译(二十) 动态性能分析方法与工具
如果对象图从开始(或根)节点到y的每个路径都必须经过x,则对象x支配对象y
某个对象y的直接支配者x是最靠近对象y的支配者
在支配树中,每个对象都是子对象的直接支配者,所以对象之间的依赖关系很容易被识别出来。
支配树具有以下重要属性:
属于x的子树的对象(即由x支配的对象)表示保留的x组。
如果x是y的直接支配者,那么x的直接支配者也支配y,依此类推。
支配树中的边不直接对应于来自对象图的对象引用。
【软件构造】课件精译(二十) 动态性能分析方法与工具
【软件构造】课件精译(二十) 动态性能分析方法与工具
Querying Heap Objects (OQL)
SELECT * FROM [ INSTANCEOF ] < class name=“name” > [ WHERE < filter-expression > ] < /filter-expression >< /class >
MAT允许使用自定义类SQL查询来查询堆转储。 OQL将类表示为表,将对象表示为行,将字段表示为列。
内存泄露分析
对问题发生时刻的系统内存状态获取一个整体印象。
找到最有可能导致内存泄露的元凶,通常是消耗内存最多的对象
进一步查看内存消耗最大的类/对象的具体情况,看是否有异常行为。