美文网首页
HSDB和CLHSDB

HSDB和CLHSDB

作者: 程序员札记 | 来源:发表于2022-05-17 21:57 被阅读0次

HSDB 是专门用于调试 HotSpot VM 的调试器,它是一个图形化界面。与之对应的还有个 CLHSDB-Command Line HotSpot Debugger,命令行调试界面。下面是启动命令:

java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB # 启动图形界面
java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB # 启动命令行界面

1. HSDB 图形界面

启动 HSDB 后,使用 File -> Attach to HotSpot process 连接到目标进程:

image.png

连接成功后,默认打开 Java Threads 界面,双击一个线程可查看其 OOP 信息,或者使用工具栏工具,如下:


image.png
  • Inspector:查看 OOP 和 Klass 对象信息,双击线程名称也能够查看此信息
  • Stack Memory:线程栈内存
  • Show Java Stack Traces:显示线程堆栈信息
  • Show Thread Infomation:显示线程信息
  • Find Crashes

Inspector

image.png

Stack Memory

栈内存界面有 3 栏信息,从左到右依次是:内存地址,指虚拟地址不是物理地址;该地址数据,以字宽为单位,如下图是在64位的机器的情况,字宽就是64位=8字节;相关注释,竖线表示范围,横线表示说明。

image.png

Tools 工具栏也变得可用,主要有以下功能:

image.png
  • Class Browser:类浏览器
  • Code Viewer: 代码查看
  • Compute Reverse Ptrs:反向指针计算
  • Deadlock Detection: 死锁探测
  • Find Object by Query: 使用对象查询语言查询对象
  • Find Pointer:查找指针
  • Find Value in Heap:在堆中查询
  • Find Value in Code Cache:在Code Cache 中查询
  • Heap Parameters:堆信息
  • Inspector:对象检查器
  • Memory Viewer: 内存信息
  • Monitor Cache Dump:监控Cache信息
  • Object Histogram: 对象直方图
  • Show System Properties:显示系统属性
  • Show VM Version:显示 VM 版本
  • Show –XX flags:显示 VM 选项

使用 Heap Parameters 查看堆信息,能够查看出各代的地址空间:

image.png
package jvmTest;
 
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
 
interface interTest{
    void show();
}
 
class Base{
    public int a;
 
    public Base(int a) {
        this.a = a;
    }
}
 
class A extends Base implements interTest  {
    public int b;
    public A(int a,int b) {
        super(a);
        this.b=b;
    }
 
    @Override
    public void show() {
        System.out.println("a->"+a+",b="+b);
    }
}
 
 
public class MainTest {
 
    public static void main(String[] args) {
        String s="shl";
        String[] s2={"shl","abc","bcd"};
        A a=new A(1,2);
        a.show();
        while (true){
            try {
                System.out.println(getProcessID());
                Thread.sleep(600*1000);
            } catch (Exception e) {
 
            }
        }
    }
 
    public static final int getProcessID() {
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        System.out.println(runtimeMXBean.getName());
        return Integer.valueOf(runtimeMXBean.getName().split("@")[0])
                .intValue();
    }
}

执行main方法后就可从控制台获取进程ID。

2、JAVA THREADS窗口

进入JAVA_HOME的lib目录下,在命令行执行java -cp ./sa-jdi.jar sun.jvm.hotspot.HSDB就可唤起HSDB的图形界面,点击File-》Attach to Hotspot Process,输入进程ID,点击OK,

第一次使用时会报错,如下图:

image.png

这时将jdk/jre/bin目录下的sawindbg.dll拷贝到该目录下即可,重启,attach成功后进入如下界面:

image.png

该界面显示了当前Java进程下的几个子线程,main线程就是执行main方法的用户线程,另外5个是JVM自身使用的线程,选中main线程,上述的5个按钮就都可以点击了,第一个按钮Inspect Thread是查看选中的线程对应的java.lang.Thread对象,如下图:

image.png

可以层层展开查看该对象的各属性,也可改变地址框中的对象地址,查看特定引用对象的属性

第二个按钮Stack Memery是查看当前线程的调用栈的内存,如下图所示:

image.png

一共有3列,第一列是虚拟内存地址,第二列是该内存地址上的数据,以字宽为单位,64位CPU下就是8字节,即以该地址为起始往后8字节的数据,第三列是对内存数据的注释,同颜色的竖线表示范围,横线或斜线连接范围与注释文字,Interpreted frame表示一个调用栈帧,第一个对应sleep方法的调用栈帧,第二个对应main方法的调用栈帧,最下面的是main方法创建的局部变量的地址,比较奇怪的是代码中只创建了一个String[],这里却有两个ObjAarray了?还有一个是main方法的参数String[] args。

第三个按钮show Java stack trace是显示当前线程的调用链,点击其中的方法可查看方法的字节码,如main方法,注意本地方法没有字节码所以查看不了,如下图:

image.png

其中pc表示具体的方法字节码指令地址,将滑块拖到最下面点击Constant Pool,可以查看常量池中的具体内容,如下:

image.png

第四个按钮Show thread infomation可用于查看指定线程的信息,如下图:

image.png

State是线程的状态,Stack in use是线程调用栈占用的内存的起始地址,Base of Stack是调用栈的基地址,Last_Java_SP是调用栈的当前栈帧的栈顶地址,Last_Java_SP表示调用栈的当前栈帧的栈基地址,Last_Java_PC是上一次执行的字节码指令的地址。

最后一个按钮find crashes是查找崩溃的线程。

3、TOOLS 选项

  • Class Browser用于查看类,需要用完整的类名的来查询,如下图:
image.png

@后面就该该类的类型信息或者方法的字节码指令的内存地址,点击搜索结果,可以查看该类的继承关系,方法列表,属性列表,点击方法可查看字节码,拉到底部可查看该类的常量池,如下图:

image.png
  • Code Viewer可根据内存地址查看该地址的Kclass信息或者Method信息或者字节码指令信息,如下图:
image.png
  • Computes Reserves ptrs 用于执行反向指针的分析,所谓反向指针是指根据对象地址查找指向该对象的引用的地址。
  • Deadlock Detection 用于死锁检测
  • Find Object by Query 用于通过对象查询语言查询对象,使用不方便,可参考:JVM 对象查询语言(OQL)
  • Find Pointer 查找指针
  • Find value in heap 在堆内存中查找值,输入查找的起始地址,返回堆中保存的对象信息
  • Find value in CodeCache 在代码缓存中查找值
  • Heap Paramters 显示年轻代和老年代的内存地址范围,如eden区有三个值,分别表示起始内存地址,当前已经分配的内存地址和可分配的最大内存地址,如下图:
image.png
  • Inspector 对象探视器,输入对象的内存地址,可查看该对象的所有属性信息,如下图:


    image.png
  • Memory Viewer: 内存信息
  • Monitor Cache Dump:查看当前进程使用的ObjectMonitor(用于synchronized 同步)的情况,如下图:
image.png
  • Object Histogram: 对象直方图,即所有对象的对象数量及其占用的内存空间的统计,可搜索指定类,如下图:


    image.png
  • Show System Properties:显示系统属性
  • Show VM Version:显示 VM 版本
  • Show –XX flags:显示 VM 选项

4、WINDOWS选项

 windows选项下包含两个,console和Debugger console,前者是hsdb命令行控制台,后者是hsdb自身调试用的控制台。前者实际是调用了hsdb的命令行版本CLHSDB,提供了更丰富强大灵活的命令,输入help,查看所有的命令:
image.png

参考:
Java Attach机制
JVM源码分析之Attach机制实现完全解读

二、CLHSDB

进入JAVA_HOME的lib目录下,在命令行执行java -cp ./sa-jdi.jar sun.jvm.hotspot.CLHSDB就可唤起CLHSDB的命令行界面了,执行attach 进程ID可attach到本地或者远程的java进程,采用跟HSDB同样的测试用例。

既可以在 HSDB 中使用 Windows –> Console 进行命令行界面,也可以使用 Java 命令直接连接到 CLHSDB 如图:

image.png

CLHSDB 提供了丰富的命令,使用 help 查看帮助信息,以下简单介绍常用的命令:

  • attach pid|exec core:连接 Java进程或 core文件

  • class name:查看类信息

  • classes:查看加载的类

  • detach:断开连接

  • inspect expression:查看 OOP 信息

  • jstack [-v]:线程堆栈

  • mem address [length]:查看内存,以字宽为单位

  • print expression:输出表达式值

  • revptrs:反向指针

  • scanoops start end [type]:扫描指定空间中的 type 类型及其子类的实例

  • thread {-a|id}:查看指定线程信息

  • threads:查看所有线程信息

  • universe:查看堆空间信息

  • whatis address:查看指定地址存放的数据信息

  • quit:退出

通过 HSDB和CLHSDB 可以查看 JVM 内部信息,从本质上去了解 JVM 的工作原理。

1、THREADS和THREAD

输入threads可以查看所有的子线程,输入thread 线程id可以查看该线程的详情


image.png image.png

第一行Thread 1 Address是Thread实例的地址。

2、CLASSES和CLASS

classes是列出已经加载的所有的类的类型信息,class 完整类名是查找该类的类型信息,如下图:

image.png

3、INSPECT

同图形界面的Inspect,用于查看指定地址的类(C++的类)的各属性信息,如下图:


image.png

4、 JSTACK

jstack用于查看是否存在死锁,查看所有线程的调用栈,加上-v选项可以输出详细的内存地址信息,如下图:

image.png

5、UNIVERSE

universe同图形界面中的Heap Paramters选项,显示年轻代和老年代堆内存的地址范围,如下图:

image.png

6、SCANOOPS

用于在指定地址范围内搜索所有指定类型的所有实例(Oop),后跟起始地址和类型信息,然后通过inspect 可查看具体的实例属性,如下图:

image.png

7、REVPTRS

revptrs可根据对象地址查看引用该对象的活跃对象的地址,这里的引用是指通过类全局属性而非局部变量引用,修改上述测试用例在类A中增加一个私有属性,private Base ba=new Base(1);,然后依次执行universe,scanoops,revptrs,inspect命令,如下图:

image.png

8、MEM

mem命令可查看指定起始地址和以位宽为单位的长度的内存的数据,64位CPU的位宽是8字节,如下图:


image.png

A实例的内存大小是24字节,依次是8字节的对象头,4字节的属性a,4字节的指向Kclass的压缩指针,4字节的指向Base实例的压缩指针,4字节的属性b。

其他命令可参考OpenJDK 下hotspot/agent/src/share/sun/jvm/hotspot/CommandProcessor的实现。

9、PRINT

输入一个Klass*, Method*的地址,可以打印该类或者方法,效果等同于Code Viewer选项,如下图:

image.png

**10、WHERE **

通过threads可查看所有的线程,输入线程id,查看该线程的调用栈,输入-a,查看所有线程的调用栈,如下图:

image.png

11、PRINTAS

后跟一个Hotspot Type和地址,会打印该Type对象的各属性,效果同inspect命令,不过不局限与oop,也可以是对象的真实地址。如下图:

image.png

12、PRINTSTATICS

printstatics 可以用于获取Hotspot 定义的C++类的静态属性,如表示Java堆内存的Universe对象,如下图:

image.png

13、PRINTMDO

printmdo用于打印指定地址的MethodData对象,该对象保存了Profile统计的方法性能的数据,如下图:

image.png

相关文章

  • HSDB和CLHSDB

    HSDB 是专门用于调试 HotSpot VM 的调试器,它是一个图形化界面。与之对应的还有个 CLHSDB-Co...

  • 使用HSDB验证Class对象和类的静态对象保存在堆中

    HSDB(Hotspot Debugger) 运行 本文使用的时命令行CLHSDB。由于HSDB会先attach进...

  • HSDB

    1 定义 HSDB ( Hotspot Debugger) 。 jdk自带的 检查调试java进程的工具。最近在深...

  • 使用HSDB

    HSDB(Hotspot Debugger),JDK自带的工具,用于查看JVM运行时的状态。 HSDB位于C:\P...

  • The Top-Level HotSpot Debugger -

    HSDB: The top-level HotSpot Debugger debuggergdb c,c++ ba...

  • JVM-HSDB

    进入目录 执行命令 其他:查看java进程id: 学习参考 https://www.yidot.net/singl...

  • JVM

    查看字节码文件:javap -c Person.class使用HSDB查看内存:E:\JDK\jdk1.8.0\...

  • HSDB(Hotspot Debugger) 使用

    1. JAVA_HOME确认,方便起见, 添加sa-jdi.jar到classpath中 source .bash...

  • 动态代理Cglib原理

    1. 工具使用:HSDB 2. 测试代码:(对Subject中的方法增强打印开始时间和结束时间) 3. 断点获取如...

  • HSDB 在mac下的启动和使用

    1.查询jdk所在文件夹 查询结果根据本机环境大同小异,这是笔者结果: 2.打开HSDB 执行下面一行命令 这里需...

网友评论

      本文标题:HSDB和CLHSDB

      本文链接:https://www.haomeiwen.com/subject/wnznurtx.html