zoukankan      html  css  js  c++  java
  • 第一次使用HSDB

    今天看了几篇大佬关于HSDB使用的文章,自己也依样画葫芦的用来一下,强大的一匹!!!

    HSDB(Hotspot Debugger),JDK自带的工具,用于查看JVM运行时的状态。

    HSDB位于C:Program FilesJavajdk1.8.0_212lib里面,接下来启动HSDB:

    1 java -cp .sa-jdi.jar sun.jvm.hotspot.HSDB

      正常启动之后界面是这样的:

      一篇空白,没啥好看的。当然有的同学可能启动的时候会报错,我启动的时候也是报错了的:

      这个错是说有个.dll文件没找到,然后寻找的路径是C:Program FilesJavajre1.8.0_212in,是去我的jre里面去找的,我在安装jdk的时候选择安装了外部的jre

      然后我就去jdk里面找了一下有没有这个dll文件,还真有,我就给copy到外部jre里面对应的目录里面了,接着启动HSDB就没有问题啦。

      接着上面的,我们已经启动了HSDB,接下来可以关联到具体的JVM进程了,我这里准备了一段代码并启动,今天的用HSDB对JVM进行分析,就跟着这段代码走了

     1 public abstract class A {
     2 
     3     public void printMe() {
     4         System.out.println("I love vim");
     5     }
     6     public abstract void sayHello();
     7 
     8 }
     9 
    10 public class B extends A{
    11 
    12     @Override
    13     public void sayHello() {
    14         System.out.println("hello, i am child B");
    15     }
    16 
    17 }
    18 
    19 public class MyTest {
    20 
    21     public static void main(String[] args) throws IOException {
    22         A obj = new B();
    23         System.in.read();
    24         System.out.println(obj);
    25     }
    26 
    27 }

      运行代码之后,会卡在System.in.reda();这里,于是我们可以查看JVM的进程,这里我是用jps命令来查看:

      可以看到刚才运行的代码的PID是5360,我们在HSDB里面去关联进程:

      File > Attach to Hotspot process

      进来之后首先看到就是当前进程里面的线程:

      好,到此一步,我们前面的准备工作已经OK了,接下来我们的目的就是分析多态情况下的虚方法表,具体来说就是分析B对象的vtable,首先找到B对象的

    内存指针地址:

      Tools > Class Browser

      B对象的地址是0x0000000100062028,然后我们去看这个对象的详细信息:

      Tools > Inspector

      找到有一行是vtable的,那就是该对象的虚方法表了,我这里是:

      咦,为什么虚方法表现是方法有七个呢?这是因为,万物皆对象,对象都继承自Object,所以B对象继承了Object的5个方法,然后继承了A的一个方法,自己重写了

    一个方法,所以是七个,如何验证呢?

      我们可以用mem命令来查看,当然要先知道vtable的内存起始地址。这里可以这样算,因为vtable是在instanceKlass对象实例的尾部,而instanceKlass大小在

    64 位系统的大小为 0x1B8,因此 vtable 的起始地址等于 instanceKlass 的内存首地址加上 0x1B8 等于 0x00000007C00605D0

      接下类我们就用算出这个地址1000621E0去看:

      Windows > Console

      第一列是方法实际在堆中的内存地址,第二列则是内存指针地址,于是我们拿到内存指针地址去A,B和Object中分别查看,可以看到前5行对应的是Object

    的方法,第6行对应的是A对象中的方法,第7行则对应B对象中的方法,由此我们可以得出以下结论:

    1.vtable 是 Java 实现多态的基石,如果一个方法被继承和重写,会把 vtable 中指向父类的方法指针指向子类自己的实现。
    2.Java 子类会继承父类的 vtable。Java 所有的类都会继承 java.lang.Object 类,Object 类有 5 个虚方法可以被继承和重写。当一个类不包含任何方法时,vtable 的长度也最小为 5,表示 Object 类的 5 
    个虚方法
    3.finalstatic 修饰的方法不会被放到 vtable 方法表里 4.当子类重写了父类方法,子类 vtable 原本指向父类的方法指针会被替换为子类的方法指针
    5.子类的 vtable 保持了父类的 vtable 的顺序

      参考文章:

      jvm 性能调优工具之 jps

      借HSDB来探索HotSpot VM的运行时数据

      通过HSDB来了解String值的真身在哪里

      

      推荐小册:

      

  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/alinainai/p/11070923.html
Copyright © 2011-2022 走看看