分类 Java 相关 下的文章

1-static factory - Effective Java 3rd version [学习笔记]

static factory 优点:

  1. have meaningful name;
  2. not required to create new object each time

-- Singleton;
-- Cache object;
-- Return object based on parameters;

  1. return sub-class, not current class;
  2. returned object can vary from call to call, release to release;

缺点:
难找.

可以用 .from, .of, .valueOf, .instance, .getInstance, .create, .newInstance, .getType, .type, .newType.

JVM GC 实现分类

  1. serial: 单线程 既可以年轻代 (标记复制)也可以老年代(标记清除整理);
  2. ParNew: 年轻代, 多线程版本的serial, 与 CMS 搭配使用,强交互,适合互联网应用;
  3. Parallel Scavenge: 年轻代,多线程,强调高吞吐量-通过改变年轻代大小实现, 根据参数自适应策略;
  4. ParOld: 老年代,多线程,标记整理,与 PS 搭配使用,强调高吞吐量
  5. CMS: 老年代,多线程,大多数时间与应用线程同时运行,除非并发失效,强调强交互,与 ParNew 搭配
    -- 初始标记 CMS initial mark - stop the world
    -- 并发标记 CMS concurrent mark
    -- 重新标记 CMS remark - stop the world
    -- 并发清除 CMS concurrent sweep
    浮动垃圾 和 并发失效 (内存不够) -> serial old 和 垃圾碎片
    设置的 CMSInitiatingOccupancyFraction 的大小和次数的 tradeoff
  6. G1: 多线程,既年轻代,又老年代,适合大于大内存,分 region;
    -- 可预测的停顿时间模型
    -- 回收价值列表 - 优先级

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

Java 常见的三种 dump 文件: Core Dump, heap dump, thread dump

  1. core dump: 有时又被称作 crash dump, memory dump, system dump, 它是某个进程在某个时间点的内存镜像. 它既可以在系统发生致命错误或无法处理的错误时候自动产生, 也可以通过命令工具产生. 但是 core dump 一遍并不能包含所有的内存页,但至少包含 heap 和 stack 的内存信息. core dump 默认放在当前进程的工作文件夹,并以core.pid 命名. 使用 jmap 转换 core dump 为 HPROF 文件(jmap -dump:format=b,file=dump.hprof /usr/bin/java core.1234) 或使用 Java VisualVM 来分析都可以. 也可以在 Linux 上面用 gdb --core core.1234 来分析.
  2. heap dump: 内存某个时间点镜像, 有ASCII 或 binary 格式,不同格式可能包含的信息不一样. 但一般包含 heap 里的类和对象实例信息. 但不包含什么时候或什么原因对象产生.
  3. thread dump: The thread dump consists of the thread stack, including thread state, for all Java threads in the virtual machine. The thread dump does not terminate the application: it continues after the thread information is printed.

如何使用 Java VisualVM 来分析 core dump
转换 core dump 为 HPROF 文件

_$jmap -dump:format=b,file=dump.hprof /usr/bin/java core.1234  //这个 java 是你 core dump 运行的 java
  • 如何产生 core dump
  • 如何产生 heap dump or 这里 or 这里
    -- 应用启动时: _$ java -agentlib:hprof=file=snapshot.hprof,format=b application
    -- 应用启动时: _$ java -XX:+HeapDumpOnOutOfMemoryError application
    -- _$ jcmd GC.heap_dump filename=Myheapdump
    -- _$ jmap -dump:format=b,file=snapshot.jmap pid
    -- 使用 JConsole 工具
  • 如何产生 thread dump
    -- _$ jstack -f 5824
    -- use VisualVM