关于btrace的使用总结:
使用步骤:
一、下载btrace包:btrace-agent.jar、btrace-boot.jar、btrace-client.jar。
二、在环境变量中配置BTRACE_HOME。在PATH中添加BIN目录的路径。
三、运行要测试的web应用,这里使用本机上的web应用做测试例子。
四、用jps获取当前进程id。
五、编写btrace监控脚本监控web应用中特定类的运行情况。
六、使用btrace
自己的测试例子:
2、 这里测试的是监控某个类中init的调用状况。
3、 编写的btrace脚本:
package com.btrace.demo;
import static com.sun.btrace.BTraceUtils.print;
import static com.sun.btrace.BTraceUtils.printArray;
import static com.sun.btrace.BTraceUtils.println;
import static com.sun.btrace.BTraceUtils.probeClass;
import static com.sun.btrace.BTraceUtils.probeMethod;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
@BTrace
public class BtraceDemo {
@OnMethod(clazz="classpath(监控类的完整路径)",method="init")
public static void test(){
print("demo.init..............start...............");
print(" [");
print(probeMethod());
println("]");
print("demo.init..............start...............");
}
}
4、 使用jps查看jboss启动的进程id(我本机上当前的pid是46812)
5、 使用btrace命令启动脚本并将监控情况写入日志btrace -cp D:\btrace\build 46812 BtraceDemo.java > c:\btracelog.txt。
6、 Btracelog.txt日志记录的情况:
demo.init..............start............... [init]
demo.init..............start...............
demo.init..............start............... [init]
demo.init..............start...............
demo.init..............start............... [init]
demo.init..............start...............
由此可见init方法被调用了3次。
感想:btrace这种弱侵入式监控应用运行状态的工具太棒了。可以随时随地的监控online的应用和程序。而且工具小巧方便,容易入门。
关于jvm学习总结:
一个java虚拟机实例的运行过程:
1、运行java虚拟机的启动程序,设置jvm运行时的参数。
2、由启动程序去启动真正的虚拟机,也就是jre目录下的jvm.dll。
3、由类装载器将编译后的文件装载进虚拟机中。
4、由执行引擎找到main方法入口,从方法区中将字节码读取到执行引擎中,并逐句开始执行。(方法区中存放的是被类装载器装载进虚拟机的class的信息,该class信息是从Class文件中读取的)。
5、在执行过程中,如果需要在main中生成某个类的对象,执行引擎会在方法区中的常量池去寻找与该类名称对应的类的信息,然后在java堆中为此对象分配内存空间。
6、当在mian方法中有调用某个对象的方法时,同样的,执行引擎会去常量池中寻找与此方法名对应的方法,并通过其中存放的字节码所在内存区域的指针去将方法字节码读入寄存器,通过执行引擎执行。在执行方法字节码的同时,由于在编译时就已经指定每个方法的操作数栈和局部变量区的大小,所以此时,执行引擎会在java栈中压入一个栈帧(java中一个线程只有一个栈,在一个线程中调用方法,方法栈会以栈帧的形式压入到当前线程拥有的栈中)。如果是调用的native方法,则在本地方法栈中压入栈帧。
以下是一个java source文件和其Class文件的对比描述:
(1)此为java source文件
public class SimpleObj{
private Object simpleobj;
public void setSim(Object obj){
this.simpleobj = obj;
}
public Object getSim(){
return simpleobj;
}
public static void main(String[] a){
SimpleObj simple = new SimpleObj();
simple.setSim("hello");
String demo = (String)simple.getSim();
}
}
(2)此为其对应的Class文件(使用javap –c –l –s class文件名 通过反编译得到,省略了部分)
Compiled from "SimpleObj.java"
此为常量池,里面存放了类的信息,包括方法、属性的详细信息。 |
SourceFile: "SimpleObj.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #9.#33; // java/lang/Object."
const #2 = Field #3.#34; // SimpleObj.simpleobj:Ljava/lang/Object;
const #3 = class #35; // SimpleObj
const #4 = Method #3.#33; // SimpleObj."
const #5 = String #36; // hello
const #6 = Method #3.#37; // SimpleObj.setSim:(Ljava/lang/Object;)V
const #7 = Method #3.#38; // SimpleObj.getSim:()Ljava/lang/Object;
const #8 = class #39; // java/lang/String
const #9 = class #40; // java/lang/Object
const #10 = Asciz simpleobj;
此为局部变量表 |
{
public SimpleObj();
Signature: ()V
LineNumberTable:
line 1: 0
LocalVariableTable:
真正的字节码,stack是栈帧的大小,locals是局部变量的大小,args_size是参数的大小,这些内容在编译时期就已经确定了。 |
0 5 0 this LSimpleObj;
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LSimpleObj;
。。。。。。。。。。。。。。。。。。。。。。
}
关于jmap+mat的使用总结:
这里我只使用了下jmap的dump功能,配合mat插件的使用,看了下本机上web应用运行时内存中各个类占用内存空间的情况。
使用过程如下:
1、 在jboss上运行web应用。
2、 使用jps查看jboss进程id。
3、 使用jmap -dump:format=b,file=liuyangyang.bin 49428 dump内存,生成二进制文件。
4、 在mat中导入刚才dump的liuyangyang.bin文件。
(1) 几个大对象占用内存的大小:
(2)内存中对象的查看: