提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
首先要设置jdk的家目录
sudo vim /etc/profile
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
source /etc/profile
cpu高,快速打印线程日志
如果是服务器的cpu占用过高,考虑可能是有部分线程占用cpu过高,命令如下
printf "%x\n" $(expr $(top -H p "$(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}')" -d 1 -n 60 -b |head -n 8|tail -n -1| awk '{print $1}') + 0) > /apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-thread.log&&jstack -l $(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}') >>/apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-thread.log
将TOP 1 的线程 十六进制 ID 及线程堆栈一次性输出到线程日志中
命令的详解解析如下
1、$(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}'): 这部分通过ps命令和一系列的grep和awk过滤,找到包含关键字"java"和"Simulation.*8066"的进程,并提取其进程ID(PID)。
2、$(top -H p "$(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}')" -d 1 -n 60 -b |head -n 8|tail -n -1| awk '{print $1}'): 这部分使用top命令监视指定PID的进程,然后通过一系列的head和tail命令提取第8行的信息,再通过awk提取其中的某个字段,最终得到一个数字。
3、expr $(...) + 0: 这是将前面得到的数字加上0,可能是为了强制将字符串转换为数字。
4、printf "%x\n" $(...): 这是将前面得到的数字按十六进制格式输出。
5、> /apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-thread.log: 这是将前面的十六进制数字写入一个以当前日期和时间命名的日志文件。
6、jstack -l $(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}') >> /apps/svr/logs/$(date
+%Y.%m.%d_%H.%M.%S)-thread.log: 这是获取指定PID的Java进程的线程栈信息,并将其追加到同一日志文件中。
针对上述的第二个命令进行详细解读
1、top -H: 启动 top 并显示线程(thread)级别的信息。
2、p "$(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}')": 使用子shell执行命令,找到包含关键字"java"和"Simulation.*8066"的进程,并通过 awk 提取其进程ID(PID)。
3、-d 1: 设置 top 的刷新间隔为1秒,即每秒更新一次。
4、-n 60: 设置 top 的执行次数为60次,即 top 将会运行60秒。
5、-b: 在非交互模式下运行 top,适合脚本使用。
6、| head -n 8: 通过管道将 top 输出的前8行传递给 head 命令,这里的目的是去掉 top 输出的前7行,只保留第8行以后的信息。
7、| tail -n -1: 再通过管道将 head 命令的输出传递给 tail 命令,这里的目的是去掉 top 输出的前7行,只保留最后一行,即最新的 top 输出。
8、| awk '{print $1}': 最后通过管道将 tail 命令的输出传递给 awk,提取第一个字段,即进程的PID。
综合起来,这个 top 命令的作用是监视指定PID的进程的线程信息,每秒更新一次,运行60秒,然后从中提取出与线程相关的信息。
内存过高,快速打dump
指定java_home 的情况下
jmap -dump:format=b,file=/apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-.hprof $(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}')
这个脚本使用 jmap 命令生成Java进程的堆转储文件(heap dump),并将其保存为以当前日期和时间命名的文件。让我们逐步解释这个脚本:
jmap -dump:format=b,file=/apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-.hprof: 这部分使用 jmap 命令,其中:
-dump:format=b: 指定生成的堆转储文件的格式为二进制格式。
file=/apps/svr/logs/$(date +%Y.%m.%d_%H.%M.%S)-.hprof: 指定生成的堆转储文件的路径和文件名。$(date +%Y.%m.%d_%H.%M.%S) 使用 date 命令获取当前日期和时间,并将其作为文件名的一部分。.hprof 表示堆转储文件的扩展名。
$(ps -ef|grep java |grep Simulation.*8066 |grep -v grep|awk '{print $2}'): 这部分通过一系列的 ps, grep, 和 awk 命令,找到包含关键字"java"和"Simulation.*8066"的进程,并提取其进程ID(PID)。这个PID将作为参数传递给 jmap 命令,以指定要生成堆转储文件的Java进程。
综合起来,这个脚本的目的是在指定的Java进程上运行 jmap 命令,生成一个堆转储文件,并将其保存在指定的日志路径下,文件名包含当前日期和时间。这对于分析Java应用程序的内存使用情况和排查内存相关问题非常有用。
总结
介绍了快速定位系统故障的命令