当前位置:Gxlcms > 数据库问题 > 第一次使用HSDB

第一次使用HSDB

时间:2021-07-01 10:21:17 帮助过:20人阅读

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

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

技术图片

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

技术图片

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

技术图片

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

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

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

  运行代码之后,会卡在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. <span style="color: #000000;">1.vtable 是 Java 实现多态的基石,如果一个方法被继承和重写,会把 vtable 中指向父类的方法指针指向子类自己的实现。
  2. 2.Java 子类会继承父类的 vtable。Java 所有的类都会继承 java.lang.Object 类,Object 类有 </span>5 个虚方法可以被继承和重写。当一个类不包含任何方法时,vtable 的长度也最小为 5,表示 Object 类的 5<span style="color: #000000;"> <br>个虚方法
  3. </span><span style="color: #0000ff;">3.final</span> 和 <span style="color: #0000ff;">static</span><span style="color: #000000;"> 修饰的方法不会被放到 vtable 方法表里
  4. 4.当子类重写了父类方法,子类 vtable 原本指向父类的方法指针会被替换为子类的方法指针<br>5.子类的 vtable 保持了父类的 vtable 的顺序</span>

  参考文章:

  jvm 性能调优工具之 jps

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

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

  

  推荐小册:

  技术图片

 

第一次使用HSDB

标签:替换   cep   lib   包含   main   div   margin   system   span   

人气教程排行