目录
一、Attach 黏附一个进程
前面安装的时候其实已经演示过了。这里再来一遍。
1.1 准备代码
以下是一个简单的Java程序,每隔一秒生成一个随机数,再执行质因数分解,并打印出分解结果。代码的内容不用理会这不是现在关注的点。
package demo;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MathGame {
private static Random random = new Random();
//用于统计生成的不合法变量的个数
public int illegalArgumentCount = 0;
public static void main(String[] args) throws InterruptedException {
MathGame game = new MathGame();
//死循环,每过1秒调用1次下面的方法(不是开启一个线程)
while (true) {
game.run();
TimeUnit.SECONDS.sleep(1);
}
}
//分解质因数
public void run() throws InterruptedException {
try {
//随机生成一个整数,有可能正,有可能负
int number = random.nextInt()/10000;
//调用方法进行质因数分解
List<Integer> primeFactors = primeFactors(number);
//打印结果
print(number, primeFactors);
} catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
}
}
//打印质因数分解的结果
public static void print(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer(number + "=");
for (int factor : primeFactors) {
sb.append(factor).append('*');
}
if (sb.charAt(sb.length() - 1) == '*') {
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb);
}
//计算number的质因数分解
public List<Integer> primeFactors(int number) {
//如果小于2,则抛出异常,并且计数加1
if (number < 2) {
illegalArgumentCount++;
throw new IllegalArgumentException("number is: " + number + ", need >= 2");
}
//用于保存每个质数
List<Integer> result = new ArrayList<Integer>();
//分解过程,从2开始看能不能整除
int i = 2;
while (i <= number) { //如果i大于number就退出循环
//能整除,则i为一个因数,number为整除的结果再继续从2开始除
if (number % i == 0) {
result.add(i);
number = number / i;
i = 2;
} else {
i++; //否则i++
}
}
return result;
}
}
1.2 启动Demo
我们将上面的代码打成jar包。然后通过java -jar的方式运行它。
因为它是一个死循环,所以不用担心会停止。
当然了,其实它就是arthas-demo.jar这个jar包。我们可以直接用,不用打包。
真实情况下,肯定是用自己的项目嘛。
java -jar arthas-demo.jar
效果
1.3 启动arthas
-
因为arthas-demo.jar进程打开了一个窗口,所以另开一个命令窗口执行arthas-boot.jar
-
选择要粘附的进程:arthas-demo.jar
如果粘附成功,在arthas-demo.jar那个窗口中会出现日志记录的信息,记录在/root/logs/目录下
如果端口号被占用,也可以通过以下命令换成另一个端口号执行
java -jar arthas-boot.jar --telnet-port 9998 --http-port -1
1.4 通过浏览器连接arthas
Arthas目前支持Web Console,用户在attach成功之后,可以直接访问:http://127.0.0.1:3658/。
可以填入IP,远程连接其它机器上的arthas。
默认情况下,arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用 --target-ip
参数指定listen的IP。
小结
-
启动被诊断进程
-
启动arthas-boot.jar,粘贴上面的进程
-
不但可以通过命令行的方式来操作arthas也可以通过浏览器来访问arthas
二、常用命令
2.1 dashboard 仪表盘
输入dashboard(仪表盘),按回车/enter
,会展示当前进程的信息,它隔一段时间自动刷新。按ctrl+c
可以中断执行。
注:输入前面部分字母,按tab可以自动补全命令
-
第一部分是显示JVM中运行的所有线程:所在线程组,优先级,线程的状态,CPU的占用率,是否是后台进程等
-
第二部分显示的JVM内存的使用情况
-
第三部分是操作系统的一些信息和Java版本号
2.2 cls 清屏
和Linux不一样,Linux是clear清屏,它是cls
2.3 thread 线程
thread 命令会显示所有当前正在运行的线程
thread ID 可以查询具体某一线程的详细信息
2.4 jad 反编译类
可以将class文件反编译成Java源代码。
只需通过命令 jad 类的全类名
2.5 watch 监视
它的作用是监视某个类某个方法的调用情况,包括它的返回值是什么、请求参数是什么等信息。
watch 类的全类名 方法名 returnObj
使用过程中我们可以通过tab命令来提示补全。
2.6 退出arthas
如果只是退出当前的连接,可以用quit
或者exit
命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop
命令。
三、基础命令
3.1 help
作用
查看命令帮助信息
效果
3.2 cat
作用
打印文件内容,和linux里的cat命令类似
如果没有写路径,则显示当前目录下的文件
3.3 grep
作用
匹配查找,和linux里的grep命令类似,但它只能用于管道命令
参数
参数列表 | 作用 |
---|---|
-n | 显示行号 |
-i | 忽略大小写查找 |
-m 行数 | 最大显示行数,要与查询字符串一起使用 |
-e "正则表达式" | 使用正则表达式查找 |
举例
只显示包含java字符串的行系统属性
sysprop | grep java
显示包含java字符串的行和行号的系统属性
sysprop | grep java -n
显示包含system字符串的10行信息
thread | grep system -m 10
3.4 pwd
作用
返回当前的工作目录,和linux命令类似
pwd: Print Work Directory 打印当前工作目录
效果
3.5 session
作用
查看当前会话的信息
效果
3.6 reset
作用
重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类。
简单讲就是,arthas可以增强我们运行的Java程序的某个类。
当然了,如果我们arthas服务器关闭了,这个增加也会被重置,不会改变实际运行的项目(被attach的进程)。
但是arthas服务器没有关闭的情况下,想在操作过程中重置,其实可以使用reset命令,让它停止增强。
语法
还原指定类
reset Test
还原所有以List结尾的类
reset *List
还原所有的类
reset
3.7 version
作用
输出当前目标 Java 进程所加载的 Arthas 版本号
效果
3.8 quit
作用
退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
3.9 stop
作用
关闭 Arthas 服务端,所有 Arthas 客户端全部退出
四、JVM相关命令详解
4.1 dashboard
数据说明
-
ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
-
NAME: 线程名
-
GROUP: 线程组名
-
PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
-
STATE: 线程的状态
-
CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
-
TIME: 线程运行总时间,数据格式为
分:秒
-
INTERRUPTED: 线程当前的中断位状态
-
DAEMON: 是否是daemon线程
4.2 thread
作用
查看当前 JVM 的线程堆栈信息
参数说明
参数名称 | 参数说明 |
---|---|
数字 | 线程id |
[n:] | 指定最忙的前N个线程并打印堆栈 |
[b] | 找出当前阻塞其他线程的线程 |
[i <value>] | 指定cpu占比统计的采样间隔,单位为毫秒 |
举例
展示当前最忙的前3个线程并打印堆栈
thread -n 3
当没有参数时,显示所有线程的信息
thread
显示1号线程的运行堆栈
thread 1