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))); }
}
参考文档:
- http://www.jianshu.com/p/dbb3a8b5c92f
- http://www.cnblogs.com/langtianya/p/4444025.html
java性能调优及问题追踪--Btrace的使用相关推荐
- 为什么对 Java 性能调优最后都像在调 you?
不知道你有没有发现,优化Java,或者任何其他语言的代码性能经常被当做是一种暗黑艺术. 性能分析有种神秘感.画面类似是这样的:一个「黑客」经过多年练就的手艺,能够快速深入了解某个系统,并提出神奇的解决 ...
- 11 个简练的 Java 性能调优技巧
转载自 11 个简练的 Java 性能调优技巧 想要让你的项目一直高性能运作吗?以下有一些技巧你可以拿去消除缓存瓶颈,还有一些其他的性能调优建议. 大多数开发者认为性能优化是一个复杂的话题,它需要大量 ...
- java 性能调优_Java性能调优调查结果(第四部分)
java 性能调优 这是本系列中的最后一篇文章,我们将分析我们在2014年10月进行的Java Performance Tuning Survey的结果.如果您尚未阅读第一篇文章,建议您首先阅读以下内 ...
- java 性能调优_Java性能调优调查结果(第三部分)
java 性能调优 这是本系列文章的第三篇,我们将分析2014年10月进行的调查的结果.如果您尚未这样做,我建议从本系列的前两篇文章开始: 问题严重性分析和监视域分析 . 这篇文章着重于故障排除/根本 ...
- java 性能调优_Java性能调优调查结果(第二部分)
java 性能调优 这是系列文章的第二篇,我们将分析2014年10月进行的性能调整调查的结果.如果您尚未阅读第一部分,我们建议从此处开始 . 第二部分将重点监视Java应用程序的性能问题. 特别是,我 ...
- java 性能调优_Java性能调优调查结果(第一部分)
java 性能调优 我们在2014年10月进行了Java性能调优调查.该调查的主要目的是收集对Java性能世界的见解,以改善Plumbr产品. 但是,我们也很高兴与您分享有趣的结果. 我们收集的数据为 ...
- java必读书籍_最佳5本Java性能调优书籍–精选,必读
java必读书籍 为什么Java开发人员应该阅读有关性能调优的书? 当我很久以前第一次面对这个问题时,我以为以后会做,但是我很长一段时间都没有回过头来. 仅当我在用Java编写的任务关键型服务器端财务 ...
- Java性能调优:充分利用垃圾收集器
JVM背后发生了什么,垃圾回收如何影响Java性能? 性能调优世界是一个危险的地方,一个JVM标志失衡,事情很快就会变得繁琐. 因此 ,我们决定求助于Java性能调优专家, 单调 JVM探查器mjpr ...
- Java性能调优调查结果(第一部分)
我们在2014年10月进行了Java性能调优调查.该调查的主要目的是收集对Java性能世界的见解,以改进Plumbr产品. 但是,我们也很高兴与您分享有趣的结果. 我们收集的数据为进行冗长的分析提供了 ...
最新文章
- Python大法之抛 异常
- Thinkphp的知识内容
- 特征工程tf-idf_特征工程-保留和删除的内容
- 最新版Spring Cloud Alibaba微服务架构-Openfeign服务调用篇
- 【Guava】Guava Cache的refresh和expire刷新机制
- js 匿名函数_javascript:函数的使用
- UNIX环境高级编程(第2版)第11-17章
- linux 使用秘钥认证,linux 密钥验证登录
- 静态HTML个人博客主页 简单个人网页设计作业 DW个人网站模板下载 大学生简单个人网页作品代码 个人网页制作 学生个人网页设计作业
- Renascence架构介绍——目录
- [初学笔记] tic toc 计算程序运行时间
- Java响应式编程基础-响应式流
- Browsing HDFS报错
- Asta:是什么终结了我的鸽王生涯?Go 1.13 发布!
- 教你制作第一个C++游戏!#1 引入
- 洛谷P1851 好朋友
- 拼多多开店怎么提高点击率?天创速盈提出应对措施
- java+mysql简单实现点赞评论转发帖子
- SpringCloud Edgware.SR3版本-Ribbon的timeout设置
- 等边三角形的绘制。使用turtle库中的turtle.fd()函数和turtle.seth()函数绘制一个等边三角形。
热门文章
- Linux文件系统与日志分析(inode、inode节点耗尽故障处理、文件备份和恢复、日志文件管理)
- mac开启64位内核
- 方舟编译器服务器端Java怎么用_方舟编译器可以运行Hello World了!
- flash activex java_Adobe flash player ActiveX和NPAPI和PPAPI 这三个软件有什么区别?
- cdn厂商 同兴万点_同兴万点:TXNetworks和CDNetworks让我们傻傻分不清
- 用户管理系统_【20201204】做个用户管理系统(18)——注册功能的实现(三)...
- c语言获取按键痕迹,c语言获得键盘的按键
- python csv读取数据 去掉标题-Python读csv文件去掉一列后再写入新的文件实例
- java中properties作用,java中Properties有什么用,举例说明?
- android studio中error,ERROR在Android Studio中