java性能调优及问题追踪--Btrace的使用
在生产环境中经常遇到格式各样的问题,如OOM或者莫名其妙的进程死掉。一般情况下是通过修改程序,添加打印日志;然后重新发布程序来完成。然而,这不仅麻烦,而且带来很多不可控的因素。有没有一种方式,在不修改原有运行程序的情况下获取运行时的数据信息呢?如方法参数、返回值、全局变量、堆栈信息等。Btrace就是这样一个工具,它可以在不修改原有代码的情况下动态地追踪java运行程序,通过hotswap技术,动态将跟踪字节码注入到运行类中,对运行代码侵入较小,对性能上的影响可以忽略不计。
基础说明
由于Btrace会把脚本逻辑直接侵入到运行的代码中,所以在使用上做很多限制:
- 不能创建对象
- 不能使用数组
- 不能抛出或捕获异常
- 不能使用循环
- 不能使用synchronized关键字
- 属性和方法必须使用static修饰
需要特别注意的是:不恰当的使用BTrace可能导致JVM崩溃,如在BTrace脚本使用错误的class文件,所以在上生产环境之前,务必在本地充分的验证脚本的正确性。
Btrace可以做什么?
- 接口性能变慢,分析每个方法的耗时情况;
- 当在Map中插入大量数据,分析其扩容情况;
- 分析哪个方法调用了System.gc(),调用栈如何;
- 执行某个方法抛出异常时,分析运行时参数;
- ....
参数说明:
指定分析方法的入口:@OnMethod
Btrace使用@OnMethod
注解定义需要分析的方法入口
在@OnMethod
注解中,需要指定class、method以及location等,class表明需要监控的类,method表明需要监控的方法,指定方式如下:
- 使用全限定名:clazz="com.metty.rpc.common.BtraceCase", method="add"
- 使用正则表达式:clazz="/javax.swing../", method="/./"
- 使用接口:clazz="+com.ctrip.demo.Filter", method="doFilter"
- 使用注解:clazz="@javax.jws.WebService", method=""@javax.jws.WebMethod"
- 如果需要分析构造方法,需要指定method=""
指定方法拦截的位置:@Location
定义Btrace对方法的拦截位置,通过@Location
注解指定,默认为Kind.ENTRY
- Kind.ENTRY:在进入方法时,调用Btrace脚本
- Kind.RETURN:方法执行完时,调用Btrace脚本,只有把拦截位置定义为Kind.RETURN,才能获取方法的返回结果@Return和执行时间@Duration
- Kind.CALL:分析方法中调用其它方法的执行情况,比如在execute方法中,想获取add方法的执行耗时,必须把where设置成Where.AFTER
- Kind.LINE:通过设置line,可以监控代码是否执行到指定的位置
- Kind.ERROR, Kind.THROW, Kind.CATCH
总结
Btrace能做的事情太多,但使用之前切记检查脚本的可行性,一旦Btrace脚本侵入到系统中,只有通过重启才能恢复。
通过jvisualvm
插件的方式进行测试:
安装Btrace插件
工具-->插件-->可用插件中找到BTrace Workbench
进行安装即可。
测试用例
package com.vmtools;
public class Counter {
// 总数
private static int totalCount = 0;
public int add(int num) throws Exception {
totalCount += num;
sleep();
return totalCount;
}
private void sleep() throws InterruptedException {
Thread.sleep(1000);
}
}
package com.vmtools;
import java.util.Random;
public class BtraceTest {
public static void main(String[] args) throws Exception {
Random random = new Random();
// 计数器
Counter counter = new Counter();
while (true) {
// 每次增加随机值
counter.add(random.nextInt(10));
Thread.sleep(1000);
}
}
}
Btrace测试
运行上诉测试用例
jvisualvm中找到对应的进程id-->Trace application...-->分别进行相应的测试
获取add()方法参数值和返回值。
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
//获取add()方法参数值和返回值。
@BTrace
public class TracingScript {
/* put your code here */
@OnMethod(
clazz="com.vmtools.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void func(
int a,
@Return int result) {
println("trace: =======================");
jstack();
println(strcat("a:", str(a)));
println(strcat("result:", str(result)));
}
}
定时获取Counter类的属性值totalCount
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
//定时获取Counter类的属性值totalCount。
@BTrace
public class TracingScript {
private static Object totalCount=0;
/* put your code here */
@OnMethod(
clazz="com.vmtools.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void func(@Self com.vmtools.Counter counter) {
totalCount = get(field("com.vmtools.Counter", "totalCount"), counter);
}
@OnTimer(2000)
public static void print(){
println(" ====== ");
println(strcat("totalCount: ",str(totalCount)));
}
}
获取add方法执行时间
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
//获取add方法执行时间
@BTrace
public class TracingScript {
@TLS private static long startTime = 0;
/* put your code here */
@OnMethod(
clazz="com.vmtools.Counter",
method="add"
)
public static void func(@Self com.vmtools.Counter counter) {
startTime = timeNanos();
}
@OnMethod(
clazz="com.vmtools.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void endExecute(@Duration long duration){
long time = timeNanos() - startTime;
println(strcat("execute time(nanos): ", str(time)));
println(strcat("duration(nanos): ", str(duration)));
}
}
参考文档:
java性能调优及问题追踪--Btrace的使用的更多相关文章
- Java性能调优笔记
Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多. ...
- Java性能调优(一):调优的流程和程序性能分析
https://blog.csdn.net/Oeljeklaus/article/details/80656732 Java性能调优 随着应用的数据量不断的增加,系统的反应一般会越来越慢,这个时候我 ...
- Java性能调优:利用JMC分析性能
Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JMC分析 ...
- Java性能调优:利用JFR生成性能日志
Java性能调优作为大型分布式系统提供高性能服务的必修课,其重要性不言而喻. 好的分析工具能起到事半功倍的效果,利用分析利器JMC.JFR,可以实现性能问题的准确定位. 本文主要阐述如何利用JFR生成 ...
- 第六章 Java性能调优工具(待续)
Java性能调优工具 Windows工具 JDK命令行工具 JConsole工具 Visual VM多合一工具 Visual VM对QQL的支持 MAT内存分析工具 MAT对QQL的支持 JProfi ...
- java 性能调优和GC
JAVA 性能调优和GC http://blog.csdn.net/gzh0222/article/details/7663181 JAVA GC调优手记 http://blog.csdn.net/f ...
- Java性能调优概述
目录 Java性能调优概述 性能优化有风险和弊端,性能调优必须有明确的目标,不要为了调优而调优!!!盲目调优,风险远大于收益!!! 程序性能的主要表现点 执行速度:程序的反映是否迅速,响应时间是否足够 ...
- Java性能调优攻略全分享,5步搞定!(附超全技能图谱)
对于很多研发人员来说,Java 性能调优都是很头疼的问题,为什么这么说?如今,一个简单的系统就囊括了应用程序.数据库.容器.操作系统.网络等技术,线上一旦出现性能问题,就可能要你协调多方面组件去进行优 ...
- Java性能调优实战,覆盖80%以上调优场景
Java 性能调优对于每一个奋战在开发一线的技术人来说,随着系统访问量的增加.代码的臃肿,各种性能问题便会层出不穷. 日渐复杂的系统,错综复杂的性能调优,都对Java工程师的技术广度和技术深度提出了更 ...
随机推荐
- jquery 的一些基本操作
日常使用中的操作记录,持续更新中: ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Fire ...
- jquery网页可见区域宽
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...
- ISO
- 在Arcscene绘制管线三维横断面(AE绘制三维点阵文字)
根据数据信息动态生成三维管线及横断面表格.效果图如下: 在获取信息后,直接构造点阵进行文字绘制即可. 绘制IElement代码: /// <summary> /// 绘制三维文字 /// ...
- 好用的wget命令从下载添加环境变量到各参数详解
本文是因为(笔者使用的windows系统)使用过好几次wget后,始终存在各种细节问题,于是下定决定细致的研究一下,并记录下其中细节. 下载与安装 第一步:下载wget,网络地址:http://dow ...
- C#窗体程序【用户控件-窗体】委托事件
这里的自定义控件是由普通控件组合而成的.希望事件响应代码推迟到使用自定义控件的窗体里写.步骤一:新建一个用户控件,放两个按钮,Tag分别是btn1,btn2.这两个按钮的共用单击事件处理代码如下: u ...
- OBS MAC 系统开发(基于mac OS X 10.12)
按照github 上的说明,安装配套软件,和跟踪需要的库 推荐使用homebrew 来安装各种依赖库. 安装Qt后,要配置系统变量 ,这个困扰本人很久:) 成功编译 cmake .. &&am ...
- 【BZOJ-4197】寿司晚宴 状压DP
4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 694 Solved: 440[Submit][Status] ...
- Beta阶段测试报告
前端测试计划 具体测试项如下: 注册测试 登录测试 忘记密码测试 一次登录后自动登录测试 退出登录测试 编辑资料测试 查看好友测试 搜索好友测试 添加好友测试 获取当前正在游戏的房间测试 创建房间测试 ...
- 接口返回值中数组中包含多个json对象形式
返回数据Json: { "code": , "msg": "成功", "departmentlist": [ { &qu ...