
JPDA设计架构、JVM TI和Java Agent基本原理、Java动态追踪技术
JPDAJava Platfform Debugger Architecture,是java语言定义的标准调试框架,
包括三部分 JVM TI 即JVM TOOL Interface
Java Debug Wire Protocol 定义了调试的通信协议
Java Debug Interface JDI是面向调试器开发人员的前端接口
eclipse和IDEA的调试器都是基于以上框架开发出来的
是JVM提供的native编程接口,可以获取JVM内部状态和控制java程序的执行。一般是通过建立一个Agent的方式来调用JVM TI
JVM TI典型能力:
JVM TI的Agent往往被编译成一个动态库,典型的加载方式有两种:
Agent需要用C/C++开发,JVM内置了一个名为libinstrument.so的特殊JVM TI Agent,基于Instrumention机制,开发者可以构建一个纯粹用java编写的Agent
Instrumention典型能力:
-javaagent
public class Agent{
public static void premain(String agrs,Instrumentation inst){
//todo
}
}
public class Attacher{
public static void main(String[] args) throws Exception{
VirtualMachine vm = VirtualMachine.attach(·java程序的pid·);
vm.loadAgent(agent.jar路径,);
vm.detach;
}
}
字节码修改
通过java agent结合字节码编辑器 实现 Java动态追踪技术;使用了asm开源组件
public class Agent{
public static void premain(String agrs,Instrumentation inst){
inst.addTransformer(new Transformer(),true);
Class> classz = Class.forName("MyClass");
inst.retransformClasses(classz);
}
}
//类转换器
public class Transformer implements ClassFileTransformer{
@Override
pubilc byte[] transform (ClassLoader loader,String className,Class> classBeingRedefined,ProtectionDomain domain,byte[] classfileBuffer){
//调用字节码修改器
}
}
实现字节码编辑器,asm开源接口
通过以上实现了java动态追踪技术,像Btrace、Hiprofiler/Greys/Arthas等调试工具,包括以下能力等
本地省略,
远程时
服务端设置 -agentlib:jdwp=transport=dt_socket,suspend=y,server=y,address=‘具体端口’ ;suspend=y表示启动后暂停等待客户端连接
客户端设置 Host和Port
条件断点、监控变量值、set value动态修改变量值、执行表达式、异常断点(右键OO+)、多线程调试、回到上一步(扔掉栈帧)、
IDEA功能试图Alt + 窗口数字
IDEA常用功能搜索 双shift;
全文搜索 ctrl shift F
Nacigate》Hierarchy面板 查看方法调用链
引用关系 ctrl +f7;ctrl+单击
运行时调用栈
字节码查看 安装jclasslib插件
双击ctrl run everything
Junit自动化测试 JAVA程序监控 常用监控工具 基础故障工具 jps 虚拟机进程状况工具常用 -l
jstat 虚拟机统计信息监视工具-class类加载 -compiler编译统计信息 -gc 垃圾收集统计信息
-gcutil 垃圾收集统计信息(百分比)
查看和调整虚拟机参数值
-flag
-flags 输出全部的虚拟机参数
-sysprops:输出全部系统属性
生成堆转储快照;查询finalize执行队列、java堆和方法区的详细信息
-heap
-histo[:live] 显示堆中对象的统计信息
-dump 生成dump文件,jmap -dump:live,format=b,file=heap.bin
分析jmap生成的堆转储快照
通常用VisualVM等工具来分析dump文件
生成虚拟机当前时刻的线程快照
可视化故障处理工具 Jconsole Java监视与管理控制台包括四张图表
内存、线程、类、CPU占用率
可以安装插件,VisualGC TRACER
JMC 可持续在线的监控工具MBeans服务器与VisualVM类似、差异点在JFR 飞行记录器
MAT 内存分析工具Dominator Tree 查找占用内存最多的几个对象
Histogram 查看类和对象、对象和对象的关系
选择一个class,右键 Merge Shortest 。。。> exlude all 。。。 可以分析无法释放该对象的原因
Leak Suspects
strace
pstack
pmap 查询内存映射关系,用于排查内存泄漏
vmstat 监控资源使用情况
top 显示各进程资源占用情况top -H -p
查找热点函数
生成SVG格式的火焰图
./
-t 指定线程
-e wall 采集时钟事件,包含不运行在CPU上的
-e alloc 采集当前堆栈的对象分配信息
-e lock 采集当前堆栈在monitor中的时间
微基准测试,函数级优化
运行Benchmark测试
@BenchmarkMode
@Warmup JIT预热
@Measurement 度量,测试的基本参数
JDK11支持,已经backport到JDK8,
jcmd导出jfr文件格式 jcmd pid JFR.start
jmc 打开
jfr print recording.jfr
优化点取消偏向锁 -XX:-UseBiasedLocking 非多线程的高并发
禁止衰减:-XX:UseCounterDecay GC频繁导致热点函数没被JIT编译
禁止多层编译 -XX:TieredCompilation JIT分层,如果C1编译不太好直接最高层级C2编译
数字对象AutoBox的缓存 :-XX:AutoBoxCacheMax-200000 游戏坐标等经常整形运算
查看GC真实的停顿时间-XX:+PrintGCApplicationStoppedTime
内联条件 -XX:MaxInlineSize =35 Byte JIT内联更多的方法
死锁
线程池问题 JVM内存泄漏MAT检查对象持有逻辑
堆外内存排查
JNI申请的native内存
TLS问题 Crash问题程序崩溃排查
JVM Crash日志gdb调试