Java heap dump OQL samples - where

where 可以包含:

=, <=, >, <, [ NOT ] LIKE, [ NOT ] IN, IMPLEMENTS (relational operations)
AND OR != , =
字段可以 [. ] . .

实现 group by 功能

  1. 方法1: 如果是 group by 其中一个字段 可以这样: 菜单选择 -> Java Basics -> Group by Values -> 给出类名和需要group by 的字段:
    group1.png group2.png
  2. 方法2: 使用 OQL. 举例: 假如我有很多 brave.handler.MutableSpan, 这个类有个实例字段是 name, 我想根据 name 去分组. 我们需要这么做:

    // 第0步, 我们查看我们要分组的对象
    SELECT toString(s.name), * FROM brave.handler.MutableSpan s
    
    // 第一步, 我们看看有多少唯一的 name
    SELECT DISTINCT toString(s.name) FROM brave.handler.MutableSpan s
    
    // 第二步, 做分组, 把上一步distinct的结果和原始列表对比, 第二列返回的每一行是一个list
    SELECT dn.name AS name, (SELECT OBJECTS lst FROM brave.handler.MutableSpan s WHERE (toString(s.name) = dn.name)) AS lst
    FROM 
    OBJECTS (SELECT DISTINCT toString(s.name) AS name FROM brave.handler.MutableSpan s) dn
    
    // 第三步, count 每个 group, 第二步第二列是一个list, 所以可以使用 .@length 来取长度
    SELECT g.name as name, g.lst.@length as size FROM OBJECTS ( eval((
    
    SELECT dn.name AS name, (SELECT OBJECTS s FROM brave.handler.MutableSpan s WHERE (toString(s.name) = dn.name)) AS lst
    FROM 
    OBJECTS (SELECT DISTINCT toString(s.name) AS name FROM brave.handler.MutableSpan s) dn
    
    )) ) g
  3. 使用上面第一步的结果, 然后导出到csv(菜单栏 -> 最右边-> 导出CSV), 然后excel 操作

查询 URL 相关的:

- SELECT * FROM java.net.URL u where u.port = 443
- SELECT * FROM java.net.URL u where toString(u.host) = "api.google.com"
- SELECT * FROM java.net.URL u where u.@displayName like ".*api.google.com.*"
- SELECT * FROM "com.tianxiaohui.*" u where toString(u) like ".*Metrics.*"  //正则
- SELECT s.address.holder.hostName.toString(), s.timeout FROM java.net.SocksSocketImpl s WHERE (s.port = 443) //socket 的地址和 timeout 时间
- SELECT toString(u.string) FROM java.net.URI u WHERE (toString(u.schemeSpecificPart) LIKE ".+google.com.+")

查询其它相关的:

- SELECT x.capacity FROM java.nio.DirectByteBuffer x WHERE ((toString(x.att) = "null") and (toString(x.cleaner) != "null") and (x.capacity >= (1024 * 1024)))
- SELECT DISTINCT objects x.this$0 FROM java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask x 
- SELECT distinct objects x FROM java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask x WHERE (x.this$0.toString() LIKE ".+0x468369b50")
- SELECT * FROM INSTANCEOF java.lang.Object t WHERE (toHex(t.@objectAddress) >= "0xfbd4c000" AND toHex(t.@objectAddress) <= "0xfce94050") //一段地址空间中的所有对象
- select * from java.nio.DirectByteBuffer x where x.capacity > 65535 and x.cleaner != null
- SELECT o.toString() FROM OBJECTS ( SELECT OBJECTS outbounds(t) FROM org.apache.tomcat.util.threads.TaskThread t WHERE (t.toString() = "DefaultThreadPool-23") ) o WHERE (o.toString() LIKE ".+TracingInfoImpl.+")

如果 0x789342b78 对应的地址是一个类class(不是instance), 那么可以用下面这种查法:
select * from 0x789342b78

如果要查询某个 Class 的 static 字段里面的数据:

SELECT * FROM java.lang.Class x where x.toString() LIKE ".+com.tianxiaohui.platform.config.impl.ConfigProvider.*"

如果要查询一个抽象类的具体实现:

select * from INSTANCEOF java.net.AbstractPlainSocketImpl

Java JDBC 相关的

# 一个连接有多少 open 的 ResultSet
SELECT * FROM oracle.jdbc.driver.OracleResultSetImpl rs WHERE (rs.connection.toString() LIKE ".+0x7a3af6cf8")

查看是不是包含某个关键字的字符串String:

SELECT * FROM java.lang.String s where s.toString() like ".*agepsvc.*"

查看栈桢信息

SELECT u.Thread AS Thread, u.Frame.@text AS Frame 
  FROM OBJECTS ( 
    SELECT t AS Thread, ${snapshot}.getThreadStack(t.@objectId).@stackFrames AS Frame 
      FROM java.lang.Thread t  ) u

过滤栈上面的局部变量:

SELECT vr.Thread, vr.Name, vr.Frame, vr.Local FROM OBJECTS ( 
    SELECT v.Thread AS Thread, toString(v.Thread) AS Name, v.Frame AS Frame, ${snapshot}.getObject(v.Objs) AS Local FROM OBJECTS ( 
        SELECT u.Thread AS Thread, u.Frame.@text AS Frame, u.Frame.@localObjectsIds AS Objs FROM OBJECTS ( 
            SELECT t AS Thread, ${snapshot}.getThreadStack(t.@objectId).@stackFrames AS Frame FROM INSTANCEOF java.lang.Thread t WHERE (toString(t.name) = "DefaultThreadPool-32") 
        ) u  
    ) v WHERE (v.Objs != null) 
) vr WHERE (vr.Local.toString() LIKE ".*TracingInfoImpl.*")

内置函数:

  1. toHex( number ) //转换数字为16进制
  2. toString( object ) //转换对象为 String
  3. dominators( object ) //被这个对象直接控制的
  4. dominatorof( object ) //这个对象被那些对象直接控制
  5. outbounds( object ) //
  6. inbounds( object ) //
  7. classof( object ) // 当前对象的类

如何查看一个对象的 dominator, 然后就可以用 dominatorof() 函数:

SELECT dominatorof(x) FROM OBJECTS 15038294 x 
SELECT * FROM org.ebayopensource.ginger.core.logging.impl.CalLogTransactionImpl x WHERE (dominatorof(x).toString() = "DefaultThreadPool-20")

dominator.png

更多OQL的官方文档参考: https://wiki.eclipse.org/MemoryAnalyzer/OQL

标签: none

添加新评论