使用jvisualvm.exe 的Btrace插件介绍/使用教程
一、背景
在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据信息,我们可以
通过改写代码,增加日志信息的打印,再发布到生产环境。通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部
署后环境可能已被破坏,很难重新问题的场景。
二、BTrace功能
BTrace天生就为解决这类问题而来,它可以动态地跟踪java运行程序。通过hotswap技术,动态将跟踪字节码注入到运行类中,对运行代码侵入较小,对性能上的影响可以忽略不计。
BTrace在使用上有很多限制条件,如不能创建对象、数组、抛出和捕获异常、循环等,具体限制条件参考用户文档中的BTrace
Restrictions。用户文档地址: http://kenai.com/projects/btrace/pages/UserGuide。
根据官方声明,不当地使用btrace可能导致jvm崩溃,如BTrace使用错误的.class文件,Hotspot JVM自身存在的hotswap bug等。可以先在本地验证BTrace脚本的正确性,再传到生产环境中定位问题。
三、安装步骤
1. 下载安装压缩包,最新版本的是1.2.1,下载地址: http://kenai.com/projects/btrace/downloads/directory/releases。
2. 解压缩,命令脚本放在bin目录中。
3. 设置脚本环境变量。
4. 增加脚本可执行权限。
四、使用方法
BTrace主要包含btracec和btrace两个命令编译和启动BTrace脚本:
1. btrace
功能: 用于运行BTrace跟踪程序。
命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/ 1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。
3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。
命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java
-javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]*
<MainClass> <AppArguments>
4. jvisualvm插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。

五、BTrace实战
1. 示例代码
示例代码定义了Counter计数器,有一个add()方法,每次增加随机值,总数保存在totalCount属性中。
- package com.learnworld;
- 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);
- }
- }
- }
- package com.learnworld;
- public class Counter {
- // 总数
- private static int totalCount = 0;
- public int add(int num) throws Exception {
- totalCount += num;
- sleep();
- return totalCount;
- }
- public void sleep() throws Exception {
- Thread.sleep(1000);
- }
- }
2. 常见使用场景
下面通过几个常见使用场景演示如何使用BTrace脚本。
1) 获取add()方法参数值和返回值。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add",
- location=@Location(Kind.RETURN)
- )
- public static void traceExecute(int num,@Return int result){
- println("====== ");
- println(strcat("parameter num: ",str(num)));
- println(strcat("return value:",str(result)));
- }
- }
2) 定时获取Counter类的属性值totalCount。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- private static Object totalCount = 0;
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add",
- location=@Location(Kind.RETURN)
- )
- public static void traceExecute(@Self com.learnworld.Counter counter){
- totalCount = get(field("com.learnworld.Counter","totalCount"), counter);
- }
- @OnTimer(1000)
- public static void print(){
- println("====== ");
- println(strcat("totalCount: ",str(totalCount)));
- }
- }
3) 获取add方法执行时间。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- @TLS private static long startTime = 0;
- @OnMethod(
- clazz="com.learnworld.Counter",
- method="add"
- )
- public static void startExecute(){
- startTime = timeNanos();
- }
- @OnMethod(
- clazz="com.learnworld.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)));
- }
- }
4) 获取add()方法调用方法sleep()次数。
- import com.sun.btrace.annotations.*;
- import static com.sun.btrace.BTraceUtils.*;
- @BTrace
- public class TracingScript {
- private static long count;
- @OnMethod(
- clazz="/.*/",
- method="add",
- location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
- )
- public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
- @TargetInstance Object instance, @TargetMethodOrField String method){
- println("====== ");
- println(strcat("ProbeClassName: ",pcm));
- println(strcat("ProbeMethodName: ",pmn));
- println(strcat("TargetInstance: ",str(classOf(instance))));
- println(strcat("TargetMethodOrField : ",str(method)));
- count++;
- }
- @OnEvent
- public static void getCount(){
- println(strcat("count: ", str(count)));
- }
- }
六、参考文档
1. userGuide: http://kenai.com/projects/btrace/pages/UserGuide
2. JAVA doc: http://btrace.kenai.com/javadoc/1.2/index.html
3. BTrace用户手册<译>,http://macrochen.iteye.com/blog/838920
4. btrace使用简介,http://rdc.taobao.com/team/jm/archives/509
5. btrace记忆,http://agapple.iteye.com/blog/962119
6. btrace一些你不知道的事(源码入手),http://agapple.iteye.com/blog/1005918
原文:http://learnworld.iteye.com/blog/1402763
相关文章:http://baike.baidu.com/view/10346081.htm
http://blog.csdn.net/kevin_luan/article/details/22491559
http://blog.csdn.net/qyongkang/article/details/6090497
使用jvisualvm.exe 的Btrace插件介绍/使用教程的更多相关文章
- 使用jvisualvm.exe 的Btrace插件监控应用程序
之前提到使用命令行的方式执行btrace监控,其实jdk提供更好的方式监控应用程序. 我们可以使用jvisualvm.exe加插件的方式监控,这样更加方便. 1.在jvisualvm.exe安装btr ...
- 如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码
如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码 1.Delphi编译方式介绍: 当我们在开发一个常规应用程序时,Delphi可以让我们用两种方式使用VCL,一种是把VCL中的申明 ...
- 使用jvisuamvm的btrace插件
在之前的文章中写了如何使用btrace来监控运行中的jvm的方法的参数和返回值 jvisualvm中提供了一个btrace插件,我们可以更方便地attach到一个运行中的jvm 更方便地执行和停止bt ...
- 使用jvisualvm.exe工具查看java项目内存溢出(堆溢出)
在查看内存溢出的时候,我们需要明白,堆溢出和持久代溢出,他们不一样,说到内存泄漏,我们就需要明白,内存中 年老代和新生代,和持久代,这3块的数据 自己的理解: new了一个对象,会进入到堆里面,先放 ...
- jvisualvm安装Visual GC插件
jdk自带了查看和分析jvm的一系列工具,在%JAVA_HOME%/bin目录下,包括jvisualvm.jconsole.jmap.jstack.jstat等: 其中jvisualvm.exe提供一 ...
- 【转】LiveWriter插入高亮代码插件介绍 基于SyntaxHighighter
转自:http://www.cnblogs.com/yaoshiyou/archive/2009/11/25/1610901.html 插件介绍 辛苦了两人小时写日志不小心浏览器崩溃了,发誓以后一定记 ...
- JMeter性能监测插件介绍(三)
JMeter 性能监测插件介绍 压力测试过程中,能够随时对负载服务器的健康状况的把控是相当重要的,有了这些数据,我们才能准确分析出服务器负载瓶颈.JMeter 插件包现在能够支持服务器监控,可以在所有 ...
- 【转载】Grunt常用插件介绍
项目名称 grunt-contrib v0.8.0 项目地址 https://github.com/gruntjs/grunt-contrib 项目介绍 此项目是对grunt常用插件的集合,刚接触gr ...
- 学习笔记——Maven实战(八)常用Maven插件介绍(下)
我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...
随机推荐
- [[iso教程]] 《4个月ios实体教程》全网最新、最全ios视频教程
全网最新.最全ios视频教程 内容简介 <ios实体教程>主要介绍如何使用iOS提供的强大工具集创建iOS应用.全视频对iOS操作系统做了全面的介绍,首先讲解如何构建应用程序的用户界面,涵 ...
- jquery select取值,赋值操作
select">jquery select取值,赋值操作 一.获取Select 获取select 选中的 text : $("#ddlRegType").find( ...
- Mac Pro 下使用svn
Mac 默认都会安装有svn 1.在项目下使用命令启动svn服务---svnserve -d -r 输入下列指令:svnserve -d -r /Users/apple/svn 或者输入:svnser ...
- 无法识别特性“configProtectionProvider”的解决方案
在使用.Net自身提供的加密本配置文件后再用System.Configuration.ConfigurationManager.AppSettings["key"]获取值时会抛出异 ...
- Sunny-ngrok 解决外网访问内网问题
该博文已过时 请参考官网 http://www.ngrok.cc/ 一 .进入 网址 往下拉找到: 下载不同的版本. 二. 平台登陆地址:http://www.ngrok. ...
- 美化radio和checkbox样式
HTML部分 <div id="holder"> <div> <div class="tag">Checkbox Small ...
- Crontab命令格式
第1列分钟1-59第2列小时1-23(0表示子夜)第3列日1-31第4列月1-12第5列星期0-6(0表示星期天)第6列要运行的命令 下面是crontab的格式: 分 时 日 月 星期 要运行的命令 ...
- eclipse项目部署路径
1.项目名点击右键 2.选择Build Path ------>Configure Build Path... 3.选择Source ----->Default output fol ...
- 网络基础之IPv4、网线、
=========================================Internet是一个圈子,进去这个圈子就要有相应的身份,就像我们去篮球场打球,首先得是个"人"才 ...
- Tomcat基本入门知识及发布,虚拟访问及启动碰到的错误,虚拟目录,虚拟路径,各种Tomcat的配置
Tomcat容器入门介绍 转自javaresearch.com由timgball 整理 Tomcat是一个免费的开源Web服务器,最新版本是5.5.1,支持Servlet2.4,JSP2.0,非常适合 ...