首页 > 其他 > 详细

btrace简单使用

时间:2019-12-13 09:18:24      阅读:125      评论:0      收藏:0      [点我收藏+]

基本安装

在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简单使用

原文:https://www.cnblogs.com/lijianming180/p/12032682.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!