Hotspot学习利器:HSDB和CLHSDB

标签: # JDK  jdk  hsdb

  1、测试用例:

  1. package jvmTest;
  2. import java.lang.management.ManagementFactory;
  3. import java.lang.management.RuntimeMXBean;
  4. interface interTest{
  5. void show();
  6. }
  7. class Base{
  8. public int a;
  9. public Base(int a) {
  10. this.a = a;
  11. }
  12. }
  13. class A extends Base implements interTest {
  14. public int b;
  15. public A(int a,int b) {
  16. super(a);
  17. this.b=b;
  18. }
  19. @Override
  20. public void show() {
  21. System.out.println("a->"+a+",b="+b);
  22. }
  23. }
  24. public class MainTest {
  25. public static void main(String[] args) {
  26. String s="shl";
  27. String[] s2={"shl","abc","bcd"};
  28. A a=new A(1,2);
  29. a.show();
  30. while (true){
  31. try {
  32. System.out.println(getProcessID());
  33. Thread.sleep(600*1000);
  34. } catch (Exception e) {
  35. }
  36. }
  37. }
  38. public static final int getProcessID() {
  39. RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
  40. System.out.println(runtimeMXBean.getName());
  41. return Integer.valueOf(runtimeMXBean.getName().split("@")[0])
  42. .intValue();
  43. }
  44. }

执行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,

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

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

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

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

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

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

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

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

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

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

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

3、Tools 选项

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

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

 

  • Code Viewer可根据内存地址查看该地址的Kclass信息或者Method信息或者字节码指令信息,如下图:

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

  • Inspector  对象探视器,输入对象的内存地址,可查看该对象的所有属性信息,如下图:

  • Memory Viewer:  内存信息
  • Monitor Cache Dump:查看当前进程使用的ObjectMonitor(用于synchronized 同步)的情况,如下图:

  • Object Histogram:    对象直方图,即所有对象的对象数量及其占用的内存空间的统计,可搜索指定类,如下图:

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

4、windows选项

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

   参考:Java Attach机制

              JVM源码分析之Attach机制实现完全解读

二、CLHSDB

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

1、threads和thread

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

 

      

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

 2、classes和class

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

3、inspect

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

4、 jstack 

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

5、universe

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

6、scanoops 

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

7、revptrs

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

8、mem

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

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选项,如下图:

10、where 

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

11、printas 

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

12、printstatics 

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

13、printmdo

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

版权声明:本文为y3over原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/y3over/article/details/104108385

智能推荐

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

猜你喜欢

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...

OpenStack代码贡献初体验

为什么80%的码农都做不了架构师?>>>     OpenStack如今已成为开源云平台中的明星项目,得到广泛关注。OpenStack的优秀出众依赖于众多开发者的努力,在享受其带来的便利与快捷的同时,为其做一份贡献也是一个开发者的义务。  在前段时间的OpenStack的测试过程中,我发现Nova项目中的一个Bug,于是向社区提交了Bug报...

SQL Server之8:sql查询每个学生得分最高的两门课

这是一道面试题,今天有空把它记下来,以后遇到此类问题作个参考!刚一看到这个题目,估计好多人都会想到关键字top,其实这里用到的关键字是partition, 好了,先看看表结构,及数据吧!     接下来看一看partition的功能,执行语句   结果如下:   到这里一目了然知道最终结果了!   View Code     &...