基本安装

在github上btrace项目的release下 下载最新的btrace
https://github.com/btraceio/btrace/releases

解压完后,将btrace的bin目录添加进环境变量

使用方法 btrace <options> <PID> <btrace脚本>

visualvm安装btrace

首先在visualvm中安装btrace插件
菜单栏>工具>插件>可用插件>btrace

安装完成后,如下操作

一个简单的例子

package me.cayun.javalab;

public class  {

    private static Tmp output(String s, int x) {
for (int i = 0; i < 10000; i++) {
System.out.println(s + " " + x);
} Tmp t = new Tmp();
t.setS(s);
t.setX(x);
return t;
} public static void main(String[] args) throws InterruptedException {
while (true) {
output("hello", 30);
Thread.sleep(2000);
}
}
} class Tmp {
private String s;
private int x; public String getS() {
return s;
} public void setS(String s) {
this.s = s;
} public int getX() {
return x;
} public void setX(int x) {
this.x = x;
}
}

目标

  1. 输出该函数的参数
  2. 输出该函数的执行时间
  3. 输出该函数的返回值

btrace脚本

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*; import com.sun.btrace.AnyType;
import java.lang.reflect.Field; public class TracingScript {
/* put your code here */ @OnMethod(clazz="me.cayun.javalab.BtraceMain", method="output", location=@Location(Kind.RETURN))
public static void output(String s, int b, @Return AnyType result, @Duration long runningTime) {
println(strcat("arg1: ", s));
println(strcat("arg2: ", str(b))); Class<?> clazz = classOf(result);
println(strcat("return: ", str(get(field(clazz, "s"), result))));
println(strcat("time: ", str(runningTime / 1000000)));
}
}

解释

  • @BTrace 表明这是一个btrace脚本
  • @OnMethod 指定方法入口,其中clazz和method参数可以使用正则表达式
  • @Location 表示拦截的时机,
    • Kind.ENTRY表示在进入方法时执行,默认为ENTRY
    • Kind.RETURN表示方法执行后执行
  • @Return 表示返回参数,前提location为Kind.RETURN
  • @Duration 表示函数执行时间,单位: 纳秒,前提location为Kind.RETURN
  • 获取类的某个属性值, get(field(clazz, name), object);

另一种获取函数运行时间的方法

还是刚刚那段Java代码,新的btrace脚本如下

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*; public class TracingScript {
/* put your code here */ @TLS private static long startTime; @OnMethod(clazz="me.cayun.javalab.BtraceMain", method="output")
public static void onCall() {
startTime = timeMillis();
} @OnMethod(clazz="me.cayun.javalab.BtraceMain", method="output", location=@Location(Kind.RETURN))
public static void onReturn() {
println(str(timeMillis() - startTime));
}
}

解释

  • @TLS 用来将一个脚本变量与一个ThreadLocal变量关联

btrace直接使用项目中的类

public class  {

    public static AtomicInteger i = new AtomicInteger();

    private static void inc(int x) {
i.addAndGet(x);
} public static void main(String[] args) throws InterruptedException {
while (大专栏  btrace简单使用eyword">true) {
inc(new Random().nextInt(10));
System.out.println(i.get());
Thread.sleep(2000);
}
}
}

在第一个示例中,调用项目中的类使用的是反射的方式,但其实btrace也可以直接使用项目的类

目标

  1. 获取BtraceMain中的i的值

btrace脚本

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*; import me.cayun.javalab.BtraceMain; public class TracingScript {
/* put your code here */ @OnMethod(clazz="me.cayun.javalab.BtraceMain", method="inc")
public static void onCall(@Self BtraceMain bt) {
println(str(bt.i));
}
}

emm~,只需要在前面import相应的类即可

如果变量为私有变量,仍然需要通过反射的方式获取

btrace关于map的操作

以下代码摘自btrace源码中com.sun.btrace.BTraceUtils函数

public static void printMap(Map map) {
BTraceRuntime.printMap(map);
} public static <K, V> Map<K, V> newHashMap() {
return Collections.newHashMap();
} public static <K, V> Map<K, V> newWeakMap() {
return Collections.newWeakMap();
} public static <K, V> V get(Map<K, V> map, K key) {
return Collections.get(map, key);
} public static <K, V> boolean containsKey(Map<K, V> map, K key) {
return Collections.containsKey(map, key);
} public static <K, V> boolean containsValue(Map<K, V> map, V value) {
return Collections.containsValue(map, value);
} public static <K, V> V put(Map<K, V> map, K key, V value) {
return Collections.put(map, key, value);
} public static <K, V> V remove(Map<K, V> map, K key) {
return Collections.remove(map, key);
} public static <K, V> void clear(Map<K, V> map) {
Collections.clear(map);
} public static <K, V> int size(Map<K, V> map) {
return Collections.size(map);
} public static <K, V> boolean isEmpty(Map<K, V> map) {
return Collections.isEmpty(map);
}

其他常见用法

打印调用栈

package me.cayun.javalab;

public class  {

    private static void gc1() {
gc2();
} private static void gc2() {
gc3();
} private static void gc3() {
System.gc();
} public static void main(String[] args) throws InterruptedException {
while (true) {
gc1();
Thread.sleep(10000);
}
}
}

btrace脚本

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*; public class TracingScript {
/* put your code here */ @OnMethod(clazz="java.lang.System", method="gc")
public static void onCallGC() {
jstack();
}
}

查看VM/内存/CPU等信息

可以参考BTraceUtils的源码
https://github.com/btraceio/btrace/blob/master/src/share/classes/com/sun/btrace/BTraceUtils.java

参考

[1] btrace github
[2] BTrace 简明使用手册
[3] BTrace使用

btrace简单使用的更多相关文章

  1. Java BTrace实战(1)--BTrace的入门和使用

    前言: 对线上的java服务, 往往采用日志进行问题处理和分析. 倘若日志缺乏相关的信息时, 那又该如何处理? 远程调试会影响服务的正常工作, 修改代码重新部署的方案其实时性和灵活性难以保证(线上服务 ...

  2. Btrace入门到熟练小工完全指南

    BTrace是神器,每一个需要每天解决线上问题,但完全不用BTrace的Java工程师,都是可疑的. BTrace的最大好处,是可以通过自己编写的脚本,获取应用的一切调用信息.而不需要不断地修改代码, ...

  3. btrace 实践笔记

    btrace简介:     btrace 是一个使用在JAVA平台上面的,安全的,动态跟踪工具.它一般用于动态跟踪正在运行的jAVA程序.     使用说明在这里.下载地址在这里.     下载的时候 ...

  4. btrace拓展工具-java应用性能诊断优化利器

    Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的秘密!这是性能调优和诊断的利器! 它可以获取应用程序代码的执行时间,他可以让你无需修改代码,帮你做时间的打 ...

  5. Btrace是一个实时监控工具

    http://blog.csdn.net/gzh0222/article/details/9731031 Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的 ...

  6. Btrace

    http://www.iteye.com/topic/1005918 背景 周五下班回家,在公司班车上觉得无聊,看了下btrace的源码(自己反编译). 一些关于btrace的基本内容,可以看下我早起 ...

  7. BTrace : Java 线上问题排查神器

    BTrace 是什么 BTrace 是检查和解决线上的问题的杀器,BTrace 可以通过编写脚本的方式,获取程序执行过程中的一切信息,并且,注意了,不用重启服务,是的,不用重启服务.写好脚本,直接用命 ...

  8. Btrace官方教程-中文版

    教程英文版来源:https://github.com/btraceio/btrace/blob/master/docs/usersguide.html BTrace用户指南 BTrace是一种安全,动 ...

  9. BTrace使用小结

    简介 BTrace是一个安全的JVM动态追踪工具,最初为原Sun公司Kenai项目下面的一个子项目. 典型的使用场景是,“我要查个问题,可那个方法没有打印入口参数和返回结果日志”,“我想看某个方法的执 ...

随机推荐

  1. UML-领域模型-准则

    1.是否使用工具维护模型? 在白板上画完草图后,整理到UML工具里去 2.模型中是否要包含“票据”? 不包含,因为,票据用于退货,而本次迭代不涉及退货所以不需要体现. 总结:概念一定在本次迭代需求内的 ...

  2. 如何编写一个vue应用

    1.vue应用的组成 1.1 vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化 通常 ...

  3. C盘满了解决办法之hiberfil.sys文件

    C盘的hiberfil文件占了很大的空间: 这个是系统的休眠文件,可以通过命令关闭:powercfg -h off    [on是打开]

  4. java 里没有友元函数怎么办

    我希望一个service可以访问某个对象中的私有对象,但是不希望这个私有对象暴露给其它的service. public xxxServiceImpl{ public void do(){ xxxent ...

  5. 刷题41. First Missing Positive

    一.题目说明 题目是41. First Missing Positive,求一个未排序队列中缺失的最小正整数.时间复杂度要求是O(n).难度是Hard,确实难. 二.我的解答 不考虑时间复杂度,首先对 ...

  6. 量化投资_关于Multicharts砖型图(传统砖型图和非传统砖型图)最详细的解释_调用篇

    1. 砖图形成数组后,我们再对他们复制到数组中然后再调用出来看一下. 2. 如下是累计只取20个数组大小为例,如果开始阶段数组长度组成初始的Array[20]的长度,然后这个数组的最后一个值填满后,进 ...

  7. screen 用法

    登陆Linux服务器跑程序, 担心ssh连接被中断后,导致跑了一半的任务被强制终止. 一个比较好的办法是使用 screen 命令, 下面是使用说明 类型 命令 备注 创建 screen 查看 scre ...

  8. apache commons类库的学习

    原文地址http://www.tuicool.com/articles/iyEbquE 1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默 ...

  9. Mutation|DNM|

    生命组学 DNA序列改变的分子基础 变异来源 据研究对象,可分为两类mutation:个体上的变异和群体上的变异,群体上的变异是关联研究,eg喝酒人群vs非喝酒人群相比. 造成mutation的三类机 ...

  10. vue-router query和params参数的区别

    1.query方式传参和接收参数(相当于get请求) this.$router.push({ path:'/home' query:{ id:1 } }) 接收参数: this.$route.quer ...