栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

JAVA与JVM调试和调优

Java 更新时间:发布时间: 百科书网 趣学号

Jvm调优与调试体系深入学习笔记
  • JAVA相关调试基础
    • Java调试体系和原理
      • JPDA
      • JVM TI
      • Agent
        • Agent 加载方式
        • JVM内置 Instrumention机制
        • 编写Java Agent
        • 字节码修改
      • Java动态追踪技术
    • IntelliJ调试
      • IDEA 本地、远程调试
      • 调试技巧
      • IDEA功能试图
      • IDEA常用功能
    • Junit自动化测试
  • JAVA程序监控
    • 常用监控工具
      • 基础故障工具
        • jps 虚拟机进程状况工具
        • jstat 虚拟机统计信息监视工具
        • jinfo Java配置信息工具
        • jmap 内存映射成像工具
        • jhat (JVM Heap Analysis Tool)虚拟机堆转储快照分析工具
        • jstack java堆栈跟踪工具
      • 可视化故障处理工具
        • Jconsole Java监视与管理控制台
        • VisualVM 多合一故障处理工具
        • JMC 可持续在线的监控工具
        • MAT 内存分析工具
      • 常用linux诊断命令
    • 性能问题
      • async-profiler工具
      • jmh
      • jfr工具
      • 优化点
  • 典型问题及解决方案
    • 锁问题
    • 线程池问题
    • JVM内存泄漏
    • TLS问题
    • Crash问题
      • JVM Crash日志

近期在学习Jvm调试和调优的相关课程,做笔记如下同大家分享

JAVA相关调试基础 Java调试体系和原理

JPDA设计架构、JVM TI和Java Agent基本原理、Java动态追踪技术

JPDA

Java Platfform Debugger Architecture,是java语言定义的标准调试框架,
包括三部分 JVM TI 即JVM TOOL Interface
Java Debug Wire Protocol 定义了调试的通信协议
Java Debug Interface JDI是面向调试器开发人员的前端接口
eclipse和IDEA的调试器都是基于以上框架开发出来的

JVM TI

是JVM提供的native编程接口,可以获取JVM内部状态和控制java程序的执行。一般是通过建立一个Agent的方式来调用JVM TI
JVM TI典型能力:

  1. 各类事件(比如类加载)的钩子
  2. Java对象操控
  3. Java线程和锁操控
  4. 基本调试原语(比如断点)
Agent Agent 加载方式

JVM TI的Agent往往被编译成一个动态库,典型的加载方式有两种:

  1. 在JVM启动时通过命令行选项指定Agent加载 -agentlib 或者 -agentpath
  2. 在 JVM运行时加载(attach机制) Attach Listener
JVM内置 Instrumention机制

Agent需要用C/C++开发,JVM内置了一个名为libinstrument.so的特殊JVM TI Agent,基于Instrumention机制,开发者可以构建一个纯粹用java编写的Agent
Instrumention典型能力:

  1. redefineClasses 重新定义类
  2. retransformClasses 修改已经加载的类
    不允许新增、修改、删除、重命名已有类的字段、方法及签名和继承等
编写Java Agent

-javaagent

  1. 编写一个Java类,实现premain方法
public class Agent{
 public static void premain(String agrs,Instrumentation inst){
 //todo
	}
}
  1. 打成jar包,在MAINIFEST.MF中加入“Premain-Class”属性,指定Agent类的全类名
  2. JVM启动时加载jar包 -javaagent
  3. 如果要实现运行时加载Agent,还需要编写一个attacher类,主要代码如下
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开源组件

  1. 实现类转换器
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动态追踪技术

通过以上实现了java动态追踪技术,像Btrace、Hiprofiler/Greys/Arthas等调试工具,包括以下能力等

  • 监控指定方法的执行内容,比如入参、返回值等
  • 监控指定方法的调用情况
  • 监控指定方法的调用路径
IntelliJ调试 IDEA 本地、远程调试

本地省略,
远程时
服务端设置 -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 垃圾收集统计信息(百分比)

jinfo Java配置信息工具

查看和调整虚拟机参数值

-flag
-flags 输出全部的虚拟机参数
-sysprops:输出全部系统属性

jmap 内存映射成像工具

生成堆转储快照;查询finalize执行队列、java堆和方法区的详细信息

-heap
-histo[:live] 显示堆中对象的统计信息
-dump 生成dump文件,jmap -dump:live,format=b,file=heap.bin

jhat (JVM Heap Analysis Tool)虚拟机堆转储快照分析工具

分析jmap生成的堆转储快照
通常用VisualVM等工具来分析dump文件

jstack java堆栈跟踪工具

生成虚拟机当前时刻的线程快照

可视化故障处理工具 Jconsole Java监视与管理控制台

包括四张图表
内存、线程、类、CPU占用率

VisualVM 多合一故障处理工具

可以安装插件,VisualGC TRACER

JMC 可持续在线的监控工具

MBeans服务器与VisualVM类似、差异点在JFR 飞行记录器

MAT 内存分析工具

Dominator Tree 查找占用内存最多的几个对象
Histogram 查看类和对象、对象和对象的关系
选择一个class,右键 Merge Shortest 。。。> exlude all 。。。 可以分析无法释放该对象的原因
Leak Suspects

常用linux诊断命令

strace
pstack
pmap 查询内存映射关系,用于排查内存泄漏
vmstat 监控资源使用情况
top 显示各进程资源占用情况top -H -p

性能问题 async-profiler工具

查找热点函数
生成SVG格式的火焰图
./
-t 指定线程
-e wall 采集时钟事件,包含不运行在CPU上的
-e alloc 采集当前堆栈的对象分配信息
-e lock 采集当前堆栈在monitor中的时间

jmh

微基准测试,函数级优化
运行Benchmark测试

@BenchmarkMode
@Warmup JIT预热
@Measurement 度量,测试的基本参数

jfr工具

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调试

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/957246.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号