jstack命令介绍

jstack是Java虚拟机自带的一款轻量级诊断工具,它能够生成Java线程堆栈跟踪的快照。通过jstack,我们可以查看Java应用程序中线程的执行状态和调用堆栈,以便于对应用程序进行调试和性能分析。下面,我将详细介绍jstack的使用方法。

jstack使用步骤

1、打开命令行终端,进入Java应用程序所在的目录。
输入以下命令获取Java应用程序的进程ID(PID):

ps -ef| grep java

找到正在运行的Java应用程序的PID。

2、使用以下命令启动jstack:

jstack [PID] > stack.txt

将Java应用程序的进程ID替换为[PID],并将输出重定向到一个名为stack.txt的文件中。
打开stack.txt文件,你将看到每个线程的堆栈跟踪信息。每个线程都有自己的执行路径,包括在方法调用中的状态、线程优先级、线程状态等信息。

使用技巧:

1、如果你只想查看特定线程的堆栈信息,可以在jstack命令后面加上线程ID。例如:

jstack [PID] [TID]

其中,TID是特定线程的ID,该情况对于某些执行时间特别长的线程用来定位存在的问题非常有效。

2、可以将jstack的输出直接发送到终端进行实时查看,而不需要重定向到文件中。例如:

jstack [PID]

3、若要查看多个进程的堆栈信息,可以使用通配符。例如:

jstack [PID1] [PID2] ... [PIDn] > stack_all.txt

将所有输出重定向到一个文件中,方便查看多个进程的堆栈信息。

4、如果jstack输出的信息太多或太杂,可以使用过滤器来筛选感兴趣的信息。例如,使用grep命令来查找包含特定字符串的行:

jstack [PID] | grep "关键字"

以上就是jstack的使用方法和一些使用技巧。通过jstack工具,我们可以方便地获取Java应用程序的线程堆栈信息,帮助我们快速定位问题并进行调试。

jmap命令介绍

jmap是Java虚拟机自带的一款命令行工具,它能够生成Java堆转储快照(heap dump)文件,帮助我们查看Java应用程序的内存使用情况,诊断内存泄漏等问题。下面,我将详细介绍jmap的使用方法。

jmap使用步骤

1、打开命令行终端,进入Java应用程序所在的目录。
输入以下命令获取Java应用程序的进程ID(PID):

ps -ef | grep java

找到正在运行的Java应用程序的PID。

2、使用以下命令启动jmap:

jmap -heap [PID]

将Java应用程序的进程ID替换为[PID]。

3、查看Java堆的详细信息:
在jmap的输出中,我们可以看到Java堆的详细信息,包括每个分代的占用空间、使用垃圾回收器的名称等。通过这些信息,我们可以判断是否存在内存泄漏或其他内存问题。

使用技巧

1、如果想查看Java堆中的特定对象,可以使用jmap的-histo选项。例如:

jmap -histo:live [PID]

这将显示活动对象的大小分布情况。

2、可以将jmap的输出直接发送到终端进行实时查看,而不需要重定向到文件中。例如:

jmap -heap [PID]

3、若要查看多个进程的堆信息,可以使用通配符。例如:

jmap -heap [PID1] [PID2] ... [PIDn] > heap_all.txt

将所有输出重定向到一个文件中,方便查看多个进程的堆信息。

4、如果jmap输出的信息太多或太杂,可以使用过滤器来筛选感兴趣的信息。例如,使用grep命令来查找包含特定字符串的行:

jmap -heap [PID] | grep "关键字"

以上就是jmap的使用方法和一些使用技巧。通过jmap工具,我们可以方便地获取Java应用程序的内存使用情况,帮助我们快速定位问题并进行调试。

查看容器中的java进程和堆栈信息

1、在宿主机上通过docker命令查看docker容器ID:[DID]

docker ps

2、通过容器ID:[CID]进入容器内部

docker exec -it [CID] /bin/sh

3、查看容器内java进程的ID

ps -ef| grep java

4、通过Java自带的jstack命令和jmap查看堆栈信息

jstack [PID]

可能存在的问题和解决方案

容器内找不到jstack命令:/bin/sh: jstack: not found

对于找不到jstack命令这种情况,可以通过找到java的存储目录,然后通过直接在java目录下的/bin目录中找到该命令,然后通过全路径的方式来执行该命令,一般很多docker镜像的java目录都在/usr/lib下,可以在这里进行查找

对于进程ID为1执行jstack或jmap命令: 1: Unable to get pid of LinuxThreads manager thread

在容器中我们的很多业务进程的ID都为1,这个时候对它执行具体的命令的时候,就会出现这样的错误信息:1: Unable to get pid of LinuxThreads manager thread;对于这样的情况,我们可以通过容器和宿主机共享PID命名空间,这样当前的PID就是他在宿主机上面的进程ID啦,就不会是1啦,这样就可以对它执行相关的命令啦,对于共享PID命名空间,我们只需要在启动容器的时候增加 --p host,如下所示:

docker run --pid host busybox:latest curl

这样就可以再通过PID来执行jstack命令或者jmap命令啦