第一次使用HSDB


今天看了幾篇大佬關於HSDB使用的文章,自己也依樣畫葫蘆的用來一下,強大的一匹!!!

HSDB(Hotspot Debugger),JDK自帶的工具,用於查看JVM運行時的狀態。

HSDB位於C:\Program Files\Java\jdk1.8.0_212\lib里面,接下來啟動HSDB:

1 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 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值的真身在哪里

  

  推薦小冊:

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM