源码
//应用类,含有main()方法
public class Application {
//静态方法
public static void main(String[] args) {
// 实例化一个类对象
Studen p = new Studen(1,21,"张三");
Application t = new Application();
System.out.println(t.getClass().getName());
// 输出类中的实例属性值
System.out.println("StudenID = " + p.StudenID + ",age = " + p.age + ",name = " + p.name);
// 输出类中的静态属性值
System.out.println("classID = " + Studen.classID);
// 使用p.study(),调用对象p的方法study(),
// 并在方法study()中使用this,那么this将指向对象p。
p.study();
// 调用静态方法
Studen.showClassID("班级ID号是:");
// 实例化另一个类对象
Studen p1 = new Studen(1,21,"李斯");
}
}
class Studen {
//1、字段
//1-1 实例字段
int StudenID;
int age = 25;
String name;
//1-2 静态字段
public static int classID = 1;
//2、方法
//2-1 实例方法 含有隐式的形参变量 this
//2-1-1 实例构造方法
//编译后的方法:
//public Studen(Studen this,int StudenID,int age,String name){}
public Studen(int StudenID,int age,String name) {
this.StudenID = StudenID;
this.name = name;
this.age = age;
}
//2-1-2 实例方法
//编译后的方法:public void study(Studen this){}
public void study(){
Application t = new Application();
System.out.println(t.getClass().getName());
int a = 11;
int b = 22;
System.out.println(a + b);
System.out.println(this.name + "正在学习");
}
//2-2 静态方法 没有隐式的形参变量 this
//2-2-1 静态方法
//编译后的方法:public static void showClassID(){}
public static void showClassID(String name){
System.out.println(name + classID);
}
}
断点打在:System.out.println(a + b);
通过jhsdb查看对应的栈帧布局:
布局示意图
使用mem查看
mem -v 0x00000085d2bff2e8,0x00000085d2bff3b8
Address 0x00000085d2bff2e8: In java stack [0x00000085d2c00000,0x00000085d2bfeaf8,0x00000085d2b00000] for thread sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750:
"main" #1 prio=5 tid=0x0000023af427d750 nid=16432 at breakpoint [0x00000085d2bff000]
java.lang.Thread.State: RUNNABLE
JavaThread state: _thread_blocked
0x00000085d2bff2e8: 0x00000085d2bff2e8 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff2f0: 0x0000023a915010cb
0x00000085d2bff2f8: 0x0000000000000005
0x00000085d2bff300: 0x0000023a915014e0
0x00000085d2bff308: 0x0000000000000000
0x00000085d2bff310: 0x0000023b0c85e448 In unknown section of Java heap
0x00000085d2bff318: 0x0000023a91501120 Method Studen.study()V@0x0000023a91501120
0x00000085d2bff320: 0x0000000000000000
0x00000085d2bff328: 0x00000085d2bff358 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff330: 0x00000085d2bff3a8 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff338: 0x0000023a8753919c In interpreter codelet: return entry points [0x0000023a87538468, 0x0000023a8753a550) 8424 bytes
0x00000085d2bff340: 0x0000000000000016
0x00000085d2bff348: 0x000000000000000b
0x00000085d2bff350: 0x0000023b0c9fbe40 In unknown section of Java heap
0x00000085d2bff358: 0x0000023b0c85e5a0 In unknown section of Java heap
0x00000085d2bff360: 0x00000085d2bff360 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff368: 0x0000023a91500578
0x00000085d2bff370: 0x0000000000000005
0x00000085d2bff378: 0x0000023a915008b0
0x00000085d2bff380: 0x0000000000000000
0x00000085d2bff388: 0x0000023b0c85c3b8 In unknown section of Java heap
0x00000085d2bff390: 0x0000023a915005d0 Method Application.main([Ljava/lang/String;)V@0x0000023a915005d0
0x00000085d2bff398: 0x00000085d2bff358 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff3a0: 0x00000085d2bff3d0 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff3a8: 0x00000085d2bff5b0 In java stack for thread "main" sun.jvm.hotspot.runtime.JavaThread@0x0000023af427d750
0x00000085d2bff3b0: 0x0000023a87530fff In code in sun.jvm.hotspot.code.BufferBlob@0x0000023a87530e90
问题所在
我就很纳闷按照图中的显示,0x0000000000000016和0x000000000000000b应该在Application.main栈帧中。
Why?
0x0000000000000016和0x000000000000000b应该是Studen.study方法栈帧的一部分啊。
佐证:
javac -g Application.java javap -c Studen
public void study();
Code:
0: new #20 // class Application
3: dup
4: invokespecial #22 // Method Application."<init>":()V
7: astore_1
8: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_1
12: invokevirtual #29 // Method java/lang/Object.getClass:()Ljava/lang/Class;
15: invokevirtual #33 // Method java/lang/Class.getName:()Ljava/lang/String;
18: invokevirtual #39 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
21: bipush 11
23: istore_2
24: bipush 22
26: istore_3
27: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
30: iload_2
31: iload_3
32: iadd
33: invokevirtual #45 // Method java/io/PrintStream.println:(I)V
36: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
39: aload_0
40: getfield #16 // Field name:Ljava/lang/String;
43: invokedynamic #48, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
48: invokevirtual #39 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
51: return
Studen.study对应的字节码中bipush 11和bipush 22证明11和22是在study方法中产生的,So,JHSDB 工具的解析或标注存在问题