您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何理解java中MAT對OQL的支持,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
MAT
支持一種類似于SQL的查詢語言OQL(Object Query Language
)。OQL使用類SQL語法,可以在堆中進行對象的查找和篩選。
在MAT
中,Select
子句的格式與SQL基本一致,用于指定要顯示的列。Select
子句中可以使用“*
”,查看結果對象的引用實例(相當于outgoing references
)。
select * from java.util.Vector v
以上查詢的輸出如圖所示,在輸出結果中,結果集中的每條記錄都可以展開,查看各自的引用對象。
OQL還可以指定對象的屬性進行輸出,下例輸出所有Vector
對象的內部數組,輸出結果如圖所示。使用“OBJECTS
”關鍵字,可以將返回結果集中的項以對象的形式顯示。
SELECT OBJECTS v.elementData FROM java.util.Vector v
在Select
子句中,使用“AS RETAINED SET
”關鍵字可以得到所得對象的保留集。下例得到jvm.chapter07.Student
對象的保留集。
SELECT AS RETAINED SET * FROM jvm.chapter07.Student
“DISTINCT
”關鍵字用于在結果集中去除重復對象。下例的輸出結果中只有一條“class java.lang.String
”記錄。如果沒有“DISTINCT
”,那么查詢將為每個String
實例輸出其對應的Class
信息。
SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s
From
子句用于指定查詢范圍,它可以指定類名、正則表達式或者對象地址。
下例使用From
子句,指定類名進行搜索,并輸出所有的java.lang.String
實例。
SELECT * FROM java.lang.String s
下例使用正則表達式,限定搜索范圍,輸出所有java.lang包下所有類的實例,如圖所示。
SELECT * FROM "jvm\.chapter07\..*"
也可以直接使用類的地址進行搜索。使用類的地址的好處是可以區分被不同ClassLoade
r加載的同一種類型。下例中“0x37a014d8
”為類的地址。
select * from 0x37a014d8
有多種方法可以獲得類的地址,在 MAT
中,一種最為簡單的方法如圖所示。
在From
子句中,還可以使用“INSTANCEOF
”關鍵字,返回指定類的所有子類實例。下例的查詢返回了當前堆快照中所有的抽象集合實例,包括java.util.Vector
、java.util.ArrayList
和java.util.HashSet
等。
SELECT * FROM INSTANCEOF java.util.AbstractCollection
在From
子句中,還可以使用“OBJECTS
”關鍵字。使用“OBJECTS
”關鍵字后,那么原本應該返回類的實例的查詢,將返回類的信息。
SELECT * FROM OBJECTS java.lang.String
以上查詢的返回結果如圖所示。它僅返回一條記錄,表示java.lang.String
的類的信息。
如果不使用“OBJECTS
”關鍵字,這個查詢將返回所有的java.lang.String
實例:
“OBJECTS
”關鍵字也支持與正則表達式一起使用。下面的查詢,返回了所有滿足給定正則表達式的所有類,其結果如圖所示。
SELECT * FROM OBJECTS "jvm\.chapter07\..*"
注意:在From子句中使用OBJECTS關鍵字,將返回符合條件的類信息,而非實例信息。這與Select子句中的OBJECTS關鍵字是完全不同的。
Where
子句用于指定OQL的查詢條件。OQL查詢將只返回滿足Where
子句指定條件的對象。Where
子句的格式與傳統SQL極為相似。
下例返回長度大于10的char數組。
SELECT * FROM char[] s WHERE s.@length>10
下例返回包含“java”子字符串的所有字符串,使用“LIKE
”操作符,“LIKE
”操作符的操作參數為正則表達式。
SELECT * FROM java.lang.String s WHERE toString(s) LIKE ".*java.*"
下例返回所有value域不為null的字符串,使用“=”操作符。
SELECT * FROM java.lang.String s where s.value!=null
Where子句支持多個條件的AND、OR運算。下例返回數組長度大于15,并且深堆大于1000字節的所有Vector對象。
SELECT * FROM java.util.Vector v WHERE v.elementData.@length>15 AND v.@retainedHeapSize>1000
OQL中可以訪問堆內對象的屬性,也可以訪問堆內代理對象的屬性。訪問堆內對象的屬性時,格式如下:
[ <alias>. ] <field> . <field>. <field>
其中alias
為對象名稱。
下例訪問java.io.File
對象的path
屬性,并進一步訪問path
的value
屬性。
SELECT toString(f.path.value) FROM java.io.File f
以上查詢得到的結果如圖所示。
這些堆內對象的屬性與Java對象一致,擁有與Java對象相同的結果。
MAT為了能快捷地獲取堆內對象的額外屬性(比如對象占用的堆大小、對象地址等),為每種元類型的堆內對象建立了相對應的代理對象,以增強原有的對象功能。訪問代理對象的屬性時,使用如下格式:
[ <alias>. ] @<attribute>
其中,alias
為對象名稱,attribute
為屬性名。
下例顯示了String
對象的內容、objectid
和objectAddress
。
SELECT s.toString(), s.@objectId, s.@objectAddress FROM java.lang.String s
下例顯示了File
對象的對象ID、對象地址、代理對象的類型、類的類型、對象的淺堆大小以及對象的顯示名稱。
SELECT f.@objectId, f.@objectAddress, f.@class, f.@clazz, f.@usedHeapSize, f.@displayName FROM java.io.File f
下例顯示java.util.Vector
內部數組的長度。
SELECT v.elementData.@length FROM java.util.Vector v
下表整理了MAT代理對象的基本屬性。
對象類型 | 接口 | 接口 | 功能 |
---|---|---|---|
基對象 | IObejct | objectId | 對象ID |
基對象 | IObejct | objectAddress | 對象地址 |
基對象 | IObejct | class | 代理對象類型 |
基對象 | IObejct | clazz | 對象類類型 |
基對象 | IObejct | usedHeapSize | 淺堆大小 |
基對象 | IObejct | retainedHeapSize | 深堆大小 |
基對象 | IObejct | displayName | 顯示名稱 |
Class對象 | IClass | classLoaderId | ClassLoad的ID |
數組 | IArray | length | 數組長度 |
元類型數組 | IPrimitiveArray | valueArray | 數組內容 |
對象數組 | IObjectArray | referenceArray | 數組內容 |
除了使用代理對象的屬性,OQL中還可以使用代理對象的方法,使用格式如下:
[ <alias> . ] @<method>( [ <expression>, <expression> ] )
下例顯示int數組中索引下標為2的數據內容。
SELECT s.getValueAt(2) FROM int[] s WHERE (s.@length > 2)
下例顯示對象數組中索引下標為2的對象。
SELECT OBJECTS s.@referenceArray.get(2) FROM java.lang.Object[] s WHERE (s.@length > 2)
下例顯示了當前堆中所有的類型。
select * from ${snapshot}.getClasses()
下例顯示了所有的java.util.Vector
對象及其子類型,它的輸出如圖所示。
select * from INSTANCEOF java.util.Vector
下例顯示當前對象是否是數組。
SELECT c, classof(c).isArrayType() FROM ${snapshot}.getClasses() c
代理對象的方法整理如表所示。
對象說明 | 對象名 | 對象方法 | 對象方法說明 |
---|---|---|---|
全局快照 | ISnapshot | getClasses() | 所有實例的集合 |
全局快照 | ISnapshot | getClassesByName(String name, boolean includeSubClasses) | 根據名稱選取符合條件的實例 |
類對象 | IClass | hasSuperClass() | 是否有超類 |
類對象 | IClass | isArrayType() | 是否是數組 |
基對象 | IObject | getObjectAddress() | 取得對象地址 |
元類型數組 | IPrimitiveArray | getValueAt(int index) | 取得數組中給定索引的數據 |
元類型數組,對象數組 | [] or List | get(int index) | 取得數組中給定索引的數據 |
MAT的OQL中還內置一些有用的函數,如表所示。
表 OQL中的內置函數
函數 | 說明 |
---|---|
toHex( number ) | 轉為16進制 |
toString( object ) | 轉為字符串 |
dominators( object ) | 取得直接支配對象 |
outbounds( object ) | 取得給定對象引用的對象 |
inbounds( object ) | 取得引用給定對象的對象 |
classof( object ) | 取得當前對象的類 |
dominatorof( object ) | 取得給定對象的直接支配者 |
下例顯示所有長度為15的字符串內容(JDK 1.7導出的堆)。
SELECT toString(s) FROM java.lang.String s WHERE ((s.value.@length = 15) and (s.value != null))
下例顯示所有jvm.chapter07.Student
對象的直接支配對象。即給定對象回收后,將釋放的對象集合。
SELECT objects dominators(s) FROM jvm.chapter07.Student s
以上查詢的輸出如圖所示,顯示Student
對象支配3個Vector
對象。
函數dominatorof()與dominators()的功能相反,它獲取直接支配當前對象的對象。
SELECT distinct objects dominatorof(s) FROM jvm.chapter07.Student s
以上查詢的輸出如圖所示,顯示所有的Student
對象直接被主線程支配。
注意:函數dominatorof()與dominators()的功能正好相反。dominatorof()用于獲得直接支配當前對象的對象,而dominators()用于獲取直接支配對象。
下例取得引用WebPage
的對象。
SELECT objects inbounds(w) FROM jvm.chapter07.WebPage w
下例取得堆快照中所有在jvm.chapter
包中的存在對象實例的類型,其輸出如圖所示。
SELECT distinct objects classof(obj) FROM "jvm\.chapter07\..*" obj
關于如何理解java中MAT對OQL的支持就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。