JVM第十八讲:调试排错 - Java 问题排查之工具单
调试排错 - Java 问题排查之工具单
程序员想要有更好的发展,排查问题的能力一定得加强。举个例子:cpu100% 怎么排查,线上接口逐渐变慢了该怎么排查?慢查询该如何治理?你的思路是啥?本文是JVM第十八讲, Java 问题调试排错。Java 在线问题排查主要分两篇:本文是第二篇,通过java调试/排查工具进行问题定位。
文章目录
- 调试排错 - Java 问题排查之工具单
- 1、Java 调试入门工具
- 1.1、jps (常用)
- 1.2、jstack (常用)
- 1.3、jinfo (不常用)
- 1.4、jmap (常用)
- 1.5、jstat (常用)
- 1.6、jdb
- 1.7、CHLSDB
- 2、Java 调试进阶工具
- 2.1、btrace (常用) ☆
- 2.2、Greys
- 2.3、Arthas(常用)
- 2.4、javOSize
- 2.5、JProfiler
- 3、其它工具
- 3.1、dmesg
- 4、参考文章
1、Java 调试入门工具
1.1、jps (常用)
jps是jdk提供的一个查看当前java进程的小工具, 可以看做是 JavaVirtual Machine Process Status Tool 的缩写。
jps常用命令
jps # 显示进程的ID 和 类的名称
jps –l # 输出输出完全的包名,应用主类名,jar的完全路径名
jps –v # 输出jvm参数
jps –q # 显示java进程号
jps -m # main 方法
jps -l xxx.xxx.xx.xx # 远程查看 如果没权限,应该怎么做?
jps参数
-q:仅输出VM标识符,不包括 classname,jar name,arguments in main method
-m:输出main method的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出jvm参数
-V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
-Joption:传递参数到vm,例如:-J-Xms512m
jps原理
java程序在启动以后,会在 java.io.tmpdir 指定的目录下,就是临时文件夹里,生成一个类似于hsperfdata_User的文件夹,这个文件夹里(在Linux中为 /tmp/hsperfdata_{userName}/),有几个文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。 至于系统的参数什么,就可以解析这几个文件获得。
更多请参考 jps - Java Virtual Machine Process Status Tool
1.2、jstack (常用)
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。
jstack 常用命令:
# 基本
jstack 2815# java和native c/c++框架的所有栈信息
jstack -m 2815# 额外的锁信息列表,查看是否死锁
jstack -l 2815
jstack 参数:
-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent 的 ownable synchronizers列表.-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息-m 打印java和native c/c++框架的所有栈信息.-h | -help 打印帮助信息
更多请参考: 《JVM调优》- Jstack指令详解
1.3、jinfo (不常用)
jinfo 是 JDK 自带的命令,可以用来查看正在运行的 java 应用程序的扩展参数,包括 Java System 属性和JVM命令行参数;也可以动态的修改正在运行的 JVM 一些参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息。
jinfo常用命令:
# 输出当前 jvm 进程的全部参数和系统属性
jinfo 42609# 输出所有的参数
jinfo -flags 42609# 查看指定的 jvm 参数的值
jinfo -flag PrintGC 42609# 开启/关闭指定的JVM参数
jinfo -flag +PrintGC 42609# 设置flag的参数
jinfo -flag name=value 42609# 输出当前 jvm 进行的全部的系统属性
jinfo -sysprops 42609
jinfo参数:
no option 输出全部的参数和系统属性
-flag name 输出对应名称的参数
-flag [+|-]name 开启或者关闭对应名称的参数
-flag name=value 设定对应名称的参数
-flags 输出全部的参数
-sysprops 输出系统属性
更多请参考:jvm 性能调优工具之 jinfo
1.4、jmap (常用)
命令jmap是一个多功能的命令。它可以生成 java 程序的 dump 文件, 也可以查看堆内对象示例的统计信息、查看 ClassLoader 的信息以及 finalizer 队列。
两个用途
# 查看堆的情况
jmap -heap 42609# dump
jmap -dump:live,format=b,file=/tmp/heap2.bin 42609
jmap -dump:format=b,file=/tmp/heap3.bin 42609# 查看堆的占用
jmap -histo 42609 | head -10
jmap 参数
no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。
heap: 显示Java堆详细信息
histo[:live]: 显示堆中对象的统计信息
clstats:打印类加载器信息
finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
dump:<dump-options>:生成堆转储快照
F: 当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
help:打印帮助信息
J<flag>:指定传递给运行jmap的JVM的参数
更多请参考:jvm 性能调优工具之 jmap 和 jmap - Memory Map
1.5、jstat (常用)
jstat参数众多,但是使用一个就够了
jstat -gcutil 42609 1000
1.6、jdb
jdb可以用来预发debug,假设你预发的java_home是/opt/java/,远程调试端口是8000。那么
jdb -attach 8000
出现以上代表jdb启动成功。后续可以进行设置断点进行调试。
具体参数可见oracle官方说明 jdb - The Java Debugger
Java项目远程调试参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
1.7、CHLSDB
CHLSDB感觉很多情况下可以看到更好玩的东西,不详细叙述了。 查询资料听说jstack和jmap等工具就是基于它的。
java -classpath /opt/taobao/java/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB
更详细的可见R大此贴 http://rednaxelafx.iteye.com/blog/1847971
2、Java 调试进阶工具
2.1、btrace (常用) ☆
首当其冲的要说的是btrace。真是生产环境&预发的排查问题大杀器。 简介什么的就不说了。直接上代码干
- 查看当前谁调用了ArrayList的add方法,同时只打印当前ArrayList的size大于500的线程调用栈
@OnMethod(clazz = "java.util.ArrayList", method="add", location = @Location(value = Kind.CALL, clazz = "/./", method = "/./"))
public static void m(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod, @TargetInstance Object instance, @TargetMethodOrField String method) {if(getInt(field("java.util.ArrayList", "size"), instance) > 500){println("check who ArrayList.add method:" + probeClass + "#" + probeMethod + ", method:" + method + ", size:" + getInt(field("java.util.ArrayList", "size"), instance));jstack();println();println("===========================");println();}
}
- 监控当前服务方法被调用时返回的值以及请求的参数
@OnMethod(clazz = "com.taobao.sellerhome.transfer.biz.impl.C2CApplyerServiceImpl", method="nav", location = @Location(value = Kind.RETURN))
public static void mt(long userId, int current, int relation, String check, String redirectUrl, @Return AnyType result) {println("parameter# userId:" + userId + ", current:" + current + ", relation:" + relation + ", check:" + check + ", redirectUrl:" + redirectUrl + ", result:" + result);
}
btrace 具体可以参考这里:https://github.com/btraceio/btrace
注意:
- 经过观察,1.3.9 的 release输出不稳定,要多触发几次才能看到正确的结果
- 正则表达式匹配trace类时范围一定要控制,否则极有可能出现跑满CPU导致应用卡死的情况
- 由于是字节码注入的原理,想要应用恢复到正常情况,需要重启应用。
2.2、Greys
Greys是@杜琨的大作吧。说几个挺棒的功能(部分功能和btrace重合):
sc -df xxx:输出当前类的详情,包括源码位置和classloader结构;trace class method:打印出当前方法调用的耗时情况,细分到每个方法,对排查方法性能时很有帮助。
最牛逼的故障诊断工具!秒级定位线上问题
2.3、Arthas(常用)
Arthas是基于Greys。
具体请参考:JVM第二十讲:Java 问题排查之应用在线调试Arthas
2.4、javOSize
就说一个功能:
classes:通过修改了字节码,改变了类的内容,即时生效。 所以可以做到快速的在某个地方打个日志看看输出,缺点是对代码的侵入性太大。但是如果自己知道自己在干嘛,的确是不错的玩意儿。
其他功能Greys和btrace都能很轻易做的到,不说了。
更多请参考:官网
2.5、JProfiler
之前判断许多问题要通过JProfiler,但是现在Greys和btrace基本都能搞定了。再加上出问题的基本上都是生产环境(网络隔离),所以基本不怎么使用了,但是还是要标记一下。
更多请参考:官网
3、其它工具
3.1、dmesg
如果发现自己的java进程悄无声息的消失了,几乎没有留下任何线索,那么dmesg一发,很有可能有你想要的。
sudo dmesg|grep -i kill|less 去找关键字oom_killer。找到的结果类似如下:
[6710782.021013] java invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_scoe_adj=0
[6710782.070639] [<ffffffff81118898>] ? oom_kill_process+0x68/0x140
[6710782.257588] Task in /LXC011175068174 killed as a result of limit of /LXC011175068174
[6710784.698347] Memory cgroup out of memory: Kill process 215701 (java) score 854 or sacrifice child
[6710784.707978] Killed process 215701, UID 679, (java) total-vm:11017300kB, anon-rss:7152432kB, file-rss:1232kB
以上表明,对应的java进程被系统的OOM Killer给干掉了,得分为854。解释一下OOM killer(Out-Of-Memory killer),该机制会监控机器的内存资源消耗。当机器内存耗尽前,该机制会扫描所有的进程(按照一定规则计算,内存占用,时间等),挑选出得分最高的进程,然后杀死,从而保护机器。
dmesg日志时间转换公式:log实际时间=格林威治1970-01-01+(当前时间秒数-系统启动至今的秒数+dmesg打印的log时间)秒数:
date -d “1970-01-01 UTC echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+12288812.926194"|bc seconds” 剩下的,就是看看为什么内存这么大,触发了OOM-Killer了。
4、参考文章
- 我的java问题排查工具单
- 查看linux系统常用的命令,Linux查看系统配置常用命令
相关文章:
JVM第十八讲:调试排错 - Java 问题排查之工具单
调试排错 - Java 问题排查之工具单 程序员想要有更好的发展,排查问题的能力一定得加强。举个例子:cpu100% 怎么排查,线上接口逐渐变慢了该怎么排查?慢查询该如何治理?你的思路是啥?本文是JVM第十八讲&#…...
JAVA基础-正则表达式(12)
目录 Java 正则表达式正则表达式实例正则表达式语法 Matcher 类的方法索引方法查找方法替换方法start 和 end 方法 Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细…...
[论文笔记]GPT-1
引言 今天带来论文Improving Language Understanding by Generative Pre-Training的笔记,它的中文题目为:通过生成式预训练改进语言理解。其实就是GPT的论文。 自然语言理解可以应用于大量NLP任务上,比如文本蕴含、问答、语义相似和文档分类。虽然无标签文本语料是丰富的,…...
【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割1(综述篇)
在上一个关于3D 目标的任务,是基于普通CNN网络的3D分类任务。在这个任务中,分类数据采用的是CT结节的LIDC-IDRI数据集,其中对结节的良恶性、毛刺、分叶征等等特征进行了各自的等级分类。感兴趣的可以直接点击下方的链接,直达学习&…...
css之Flex弹性布局
文章目录 🐕前言:🏨定义flex容器 display:flex🏨在flex容器中子组件进行排列🪂行排列 flex-direction: row🪂将行排列进行翻转排列 flex-direction: row-reverse🏅按列排列 flex-direction: col…...
web.xml配置详解
在Java Web应用程序中,web.xml是一个XML配置文件,用于定义和配置Servlet、过滤器、监听器和其他Web应用程序组件的行为和属性。web.xml文件通常位于Web应用程序的WEB-INF目录下,用于描述Web应用程序的部署信息和配置。以下是一些web.xml配置的…...
关于我学习Go语言在CSDN分享的心得体会
最近我一直在学习Go语言,并通过CSDN平台分享我的学习心得和体会。在这篇博客中,我将与大家分享我在学习Go语言过程中的经验和收获。希望通过这篇博客能够帮助其他Go语言初学者更好地掌握这门语言,并与广大Go语言爱好者进行交流和互动。 选择…...
Java类的Builder应用以及使用@Data和@Builder高效应用Builder
⭐Java Builder模式:是Java设计模式之一,它属于对象创建型模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 结论一:使用lombok的Data和Builder注解构建Java类的Builder简洁高效&am…...
【Qt控件之QTabWidget】介绍及使用
描述 QTabWidget类提供了一个带有选项卡的小部件堆栈。 选项卡小部件提供了一个选项卡栏(参见QTabBar)和一个“页面区域”,用于显示与每个选项卡相关联的页面。默认情况下,选项卡栏显示在页面区域的上方,但可以使用…...
Linux实战——网络连接模式的三种模式
Linux可以分为三种网络模式: 桥接模式 (vmnet0) 仅主机模式 (vmnet1) NAT模式 (vmnet8) 当我们下载了vmware之后,在电脑会出现两个虚拟网卡,VMware Network Adapter VMnet1、VMware Network Adapter VMnet8。 可以通过查找 控…...
嵌入式实时操作系统的设计与开发(任意大小的内存管理)
任意大小的内存管理是根据用户需要为其分配内存,即用户需要多大内存就通过acoral_malloc2()为之分配多大内存,同时每块分配出去的内存前面都有一个控制块,控制块里记录了该块内存的大小。 同时未分配出去的内存也有一个控制块,寻…...
文件读取结束的判定
大家好啊,我们今天来补充文件操作的读取结束的判定。 被错误使用的feof 牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾…...
《基于 Vue 组件库 的 Webpack5 配置》9.module.exports 可为数组类型且注意编译顺序
module.exports常见是对象类型,其实也可用数组类型;注意编译顺序,从后往前 编: 也就是说先编 another.js,再编 index.js;所以代码第 9 行不能设置为 true,仅在第一次,也就是代码第19…...
CUDA学习笔记(四)device管理
本篇博文转载于https://www.cnblogs.com/1024incn/tag/CUDA/,仅用于学习。 device管理 NVIDIA提供了集中凡是来查询和管理GPU device,掌握GPU信息查询很重要,因为这可以帮助你设置kernel的执行配置。 本博文将主要介绍下面两方面内容&…...
【算法练习Day25】 重新安排行程N 皇后 解数独
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 重新安排行程N 皇后解数独总…...
软考-访问控制技术原理与应用
本文为作者学习文章,按作者习惯写成,如有错误或需要追加内容请留言(不喜勿喷) 本文为追加文章,后期慢慢追加 by 2023年10月 访问控制概念 访问控制是计算机安全的一个重要组成部分,用于控制用户或程序如…...
优测云测试平台 | 有效的单元测试
一、前言 本文作者提出了一种评价单元测试用例的质量的思路,即判断用例是否达到测试的“四大目标”。掌握识别好的用例的能力,可以帮助我们高效地写出高质量的测试用例。 评判冰箱的好坏,并不需要有制造一台冰箱的能力。在开始写测试用例之…...
Java设计模式之外观模式
定义 又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,…...
MyBatis实现延时加载的方式
MyBatis实现延时加载的方式有两种: 使用resultMap的association和collection标签配置延时加载:在查询语句中,使用association标签配置一对一关联关系,使用collection标签配置一对多关联关系。然后在查询结果映射的resultMap中配置…...
计算未来:微软眼中的人工智能
计算未来 :人工智能及其社会角色(The Future Computed. Artificial Intelligence and its role in society )这本书于2018年09月由北京大学出版社出版。 书籍的作者是:沈向洋(微软全球执行副总裁),(美&…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
