jstack 分析出线程id 如何找到进程吗

jstack 分析出线程id 如何找到进程吗,第1张

jstack 分析出线程id 如何找到进程

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。

如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。

另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

需要注意的问题:

l 不同的 JAVA虚机的线程 DUMP的创建方法和文件格式是不一样的,不同的 JVM版本, dump信息也有差别。

l 在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。

2、命令格式

$jstack [ option ] pid

$jstack [ option ] executable core

$jstack [ option ] [server-id@]remote-hostname-or-IP

参数说明:

pid: java应用程序的进程号,一般可以通过jps来获得;

executable:产生core dump的java可执行程序;

core:打印出的core文件;

remote-hostname-or-ip:远程debug服务器的名称或IP;

server-id: 唯一id,假如一台主机上多个远程debug服务;

示例:

$jstack –l 23561

线程分析:

一般情况下,通过jstack输出的线程信息主要包括:jvm自身线程、用户线程等。其中jvm线程会在jvm启动时就会存在。对于用户线程则是在用户访问时才会生成。

首先有个基本问题需要了解一下:

这里所说java里获得一个进程的内存使用情况和cpu运行时间,是指在java内部获取一个纯外部进程的内存与cpu时间呢,还是指在java内部,由java启动的进程的内存与cpu时间。

如果是第一种情况,那你还需要在java内部再起一个进程,通过执行 *** 作系统的shell命令来查看那个进程的运行状态。比如那个外部进程的ID为3119,则执行cat /proc/3119/status | grep VmRSS就可以过滤出该进程的物理内存占用量。

如果是第二种情况,(假定你问的就是这种情况)。

先说内存占用量:一般说来,你可以使用这两种方式获取内存使用情况

方式一:

MemoryMXBean memoryMXBean = ManagementFactorygetMemoryMXBean();

MemoryUsage memoryUsage = memoryMXBeangetHeapMemoryUsage(); //椎内存使用情况

long totalMemorySize = memoryUsagegetInit(); //初始的总内存

long maxMemorySize = memoryUsagegetMax(); //最大可用内存

long usedMemorySize = memoryUsagegetUsed(); //已使用的内存

方式二:

Runtime rt = RuntimegetRuntime();

long totalMemorySize = rttotalMemory(); //初始的总内存

long maxMemorySiz = tmaxMemory(); //最大可用内存

long freeMemorySize = rtfreeMemory(); //当前可用内存

需要说明的是,这种方式获取的是整个jvm的内存使用情况,并不是某一个进程的内存使用情况,事实上,在java内部,可以使用RumtimegetRuntime()exec(${SHELL})来开启一个外部进程(这里${SHELL}代表一个可 *** 作系统的shell命令)。而运行Java程序整个jvm,对于 *** 作系统而言,也仅仅只是一个进程。也就是说,一个jvm就是一个进程,你通过java程序开启的进程都是外部进程,java内部目前还提供了一个destroy方法来销毁该进程,对于该进程的其它信息,都无法直接获取,这些信息的获取,显然需要本地化(Local)的实现。既然标准jdk库没有,就不可能再通过平台无关的代码来实现了。典型的做法就是使用前面第一种情况的方式,再启一个进程,执行shell命令来获取。

不过对于cpu使用时间,采用标准java代码倒是可以拿到。由于java的语法很啰嗦,举一个较完全的例子需要太多的代码,我这里就只写最关键的代码:

ThreadMXBean threadMXBean = ManagementFactorygetThreadMXBean();

① long currentCpuTime = threadMXBeangetCurrentThreadCpuTime(); //当前线程的cpu使用时间

long someThreadId = 709817L; //假定有某个线程的ID是709817

② long someThreadCpuTime = threadMXBeangetThreadCpuTime(someThreadId); //获取ID为someThreadId即709817的线程的cpu时间

基于上面的核心api,你可以把由java启动的外部进程放到一个单独的线程中执行,再用代码②的方式来获取该进程的cpu使用时间,也可以将外部进程放入到当前线程中执行,用① 的方式来获得进程的cpu使用时间。

第一步:在终端运行Java程序

第二步:通过命令 pidof java 找到已经启动的java进程的ID,选择需要查看的java程序的进程ID

第三步:使用命令 kill -3 <java进行的 pid> 打印出java程序的线程堆栈信息

第四步:通常情况下运行的项目可能会比较大,那么这个时候打印的堆栈信息可能会有几千到几万行,为了方便查看,我们往往需要将输出内容进行重定向

使用linux下的重定向命令方式即可:例如: demosh > runlog 2>&1 将输出信息重定向到 runlog中。

注:在 *** 作系统中,0 1 2分别对应着不同的含义, 如下:

0 : 标准输入,即:C中的stdin , java中的Systemin

1 : 标准输出, 即:C中的stdout ,java中的Systemout

2 : 错误输出, 即:C中的stderr , java中的Systemerr

Demo:

----------------------------------------------------------------------------------------------

Sources Code :

public class PrintThreadTrace {

Object obj1 = new Object();

Object obj2 = new Object();

public void func1(){

synchronized (obj1){

func2();

}

}

public void func2(){

synchronized (obj2){

while(true){

Systemoutprint("");

}

}

}

public static void main(String[] args){

PrintThreadTrace ptt = new PrintThreadTrace();

pttfunc1();

}

}

----------------------------------------------------------------------------------------------------------------

按照步骤 *** 作后的打印输出信息:

Full thread dump Java HotSpot(TM) 64-Bit Server VM (2479-b02 mixed mode):

"Service Thread" daemon prio=10 tid=0x00007fdc880a9000 nid=0x12a4 runnable [0x0000000000000000]

javalangThreadState: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007fdc880a7000 nid=0x12a3 waiting on condition [0x0000000000000000]

javalangThreadState: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007fdc880a4000 nid=0x12a2 waiting on condition [0x0000000000000000]

javalangThreadState: RUNNABLE

"JDWP Command Reader" daemon prio=10 tid=0x00007fdc50001000 nid=0x1299 runnable [0x0000000000000000]

javalangThreadState: RUNNABLE

"JDWP Event Helper Thread" daemon prio=10 tid=0x00007fdc880a1800 nid=0x1298 runnable [0x0000000000000000]

javalangThreadState: RUNNABLE

"JDWP Transport Listener: dt_socket" daemon prio=10 tid=0x00007fdc8809e000 nid=0x1297 runnable [0x0000000000000000]

javalangThreadState: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007fdc88091000 nid=0x1296 waiting on condition [0x0000000000000000]

javalangThreadState: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007fdc88071800 nid=0x1295 in Objectwait() [0x00007fdc77ffe000]

javalangThreadState: WAITING (on object monitor)

at javalangObjectwait(Native Method)

- waiting on <0x00000000ecb04858> (a javalangrefReferenceQueue$Lock)

at javalangrefReferenceQueueremove(ReferenceQueuejava:135)

- locked <0x00000000ecb04858> (a javalangrefReferenceQueue$Lock)

at javalangrefReferenceQueueremove(ReferenceQueuejava:151)

at javalangrefFinalizer$FinalizerThreadrun(Finalizerjava:209)

"Reference Handler" daemon prio=10 tid=0x00007fdc8806f800 nid=0x1294 in Objectwait() [0x00007fdc7c10b000]

javalangThreadState: WAITING (on object monitor)

at javalangObjectwait(Native Method)

- waiting on <0x00000000ecb04470> (a javalangrefReference$Lock)

at javalangObjectwait(Objectjava:503)

at javalangrefReference$ReferenceHandlerrun(Referencejava:133)

- locked <0x00000000ecb04470> (a javalangrefReference$Lock)

"main" prio=10 tid=0x00007fdc8800b800 nid=0x128e runnable [0x00007fdc8fef7000]

javalangThreadState: RUNNABLE

at comwenchainstudyPrintThreadTracefunc2(PrintThreadTracejava:20)

- locked <0x00000000ecc04b20> (a javalangObject)

at comwenchainstudyPrintThreadTracefunc1(PrintThreadTracejava:13)

- locked <0x00000000ecc04b10> (a javalangObject)

at comwenchainstudyPrintThreadTracemain(PrintThreadTracejava:27)

"VM Thread" prio=10 tid=0x00007fdc8806b000 nid=0x1293 runnable

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007fdc88021000 nid=0x128f runnable

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007fdc88023000 nid=0x1290 runnable

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007fdc88024800 nid=0x1291 runnable

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007fdc88026800 nid=0x1292 runnable

"VM Periodic Task Thread" prio=10 tid=0x00007fdc880b3800 nid=0x12a5 waiting on condition

JNI global references: 1391

Heap

PSYoungGen total 17920K, used 1270K [0x00000000ecb00000, 0x00000000ede80000, 0x0000000100000000)

eden space 15872K, 8% used [0x00000000ecb00000,0x00000000ecc3d898,0x00000000eda80000)

from space 2048K, 0% used [0x00000000edc80000,0x00000000edc80000,0x00000000ede80000)

to space 2048K, 0% used [0x00000000eda80000,0x00000000eda80000,0x00000000edc80000)

ParOldGen total 39424K, used 0K [0x00000000c6200000, 0x00000000c8880000, 0x00000000ecb00000)

object space 39424K, 0% used [0x00000000c6200000,0x00000000c6200000,0x00000000c8880000)

PSPermGen total 21504K, used 2619K [0x00000000c1000000, 0x00000000c2500000, 0x00000000c6200000)

object space 21504K, 12% used [0x00000000c1000000,0x00000000c128edd8,0x00000000c2500000)

----------------------------------------------------------------------------------------------------------------------------

上面的信息中包含了当前JVM中所有运行的线程信息,其中在示例中我们启动的线程为main线程,其余的都是JVM自己创建的。

在打印的信息中,我们可以清楚的看见当前线程的调用上下文,可以很清楚的知道程序的运行情况。

并且我们在最后面还能看见当前虚拟机中的内存使用情况,青年世代,老年世代的信息等等

PS: 在JDK15以上,我们可以通过在Java程序中调用ThreadgetStackTrace()方法来进行堆栈的自动打印,使得线程堆栈的打印时机可编程控制。

文章知识点与官方知识档案匹配

Java技能树首页概览

89841 人正在系统学习中

点击阅读全文

打开CSDN,阅读体验更佳

jstack-查看Java进程的线程堆栈信息,锁定高消耗资源代码

jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下: jstack[option]pid jstack[option]executable core jstack[option][server-id@]remote-hostname-or-ip 命令行参数选项说明如下:

011Java并发包018查看线程堆栈信息_执笔未来的博客

javautilconcurrentScheduledThreadPoolExecutor$DelayedWorkQueuetake(ScheduledThreadPoolExecutorjava:1088) javautilconcurrentScheduledThreadPoolExecutor$DelayedWorkQueuetake(ScheduledThreadPoolExecutorjava:809) javautilconcurre

最新发布 jstack -- java堆栈常用排查指令

jstack -- java堆栈常用排查指令

继续访问

热门推荐 jstack 命令查看JAVA线程堆栈

JAVA堆栈信息实际生产中,可能由于开发以及测试未能全面覆盖的代码质量、性能问题,而引致线程挂起甚至崩溃。可能就需要查看堆栈信息来排查问题了。jps -lvmjps -lvm 用于查看当前机器上运行的java进程。C:\Users\Administrator>jps -lvm 7348 -DosgirequiredJavaVersion=18 -Dosgiinstanceareadefa

继续访问

Java多线程——查看线程堆栈信息

Java多线程——查看线程堆栈信息 摘要:本文主要介绍了查看线程堆栈信息的方法。 使用Thread类的getAllStackTraces()方法 方法定义 可以看到getAllStackTraces()方法的返回值是一个Map对象,key是Thread的实例,value是一个StackTraceElement实例数组: 1 public static Map<Thread, S

继续访问

java堆栈常用排查指令

java 异常排查四板斧 1、查看java 堆栈线程信息 说明 jstack命令打印指定Java进程、核心文件或远程调试服务器的Java线程的Java堆栈跟踪信息。 对于每个Java框架,完整的类名,方法名, 字节码索引(BCI)和行号(如果有的话)被打印出来。 使用-m选项,jstack命令打印程序中所有线程的Java和本机帧 计数器(PC)。 对于每个本机帧,当可用时,将打印离PC最近的本机符号。 c++乱码的名字不会被修改。 要demangle c++名称,输出这个 命令可以管道到c++filt。 当

继续访问

java诊断工具-Arthas(thread命令)查看当前线程堆栈

cpu使用率与linux 命令top -H -p <pid>的线程CPU类似 1、支持一键展示当前最忙的前N个线程并打印堆栈 thread -n 3 没有线程ID,包含[Internal]表示为JVM内部线程,参考dashboard命令的介绍。 cpuUsage为采样间隔时间内线程的CPU使用率,与dashboard命令的数据一致。 deltaTime为采样间隔时间内线程的增量CPU时间,小于1ms时被取整显示为0ms。 time线程运行总CPU

继续访问

java查看线程的堆栈信息

通过使用jps 命令获取需要监控的进程的pid,然后使用jstackpid 命令查看线程的堆栈信息。 通过jstack命令可以获取当前进程的所有线程信息。 每个线程堆中信息中,都可以查看到线程ID、线程的状态(wait、sleep、running 等状态)、是否持有锁信息等。 jstack -l <pid> >jvm_listlockstxt 转

继续访问

java 查看线程堆栈信息_Java多线程——查看线程堆栈信息

java多线程——查看线程堆栈信息摘要:本文主要介绍了查看线程堆栈信息的方法。使用thread类的getallstacktraces()方法方法定义可以看到getallstacktraces()方法的返回值是一个map对象,key是thread的实例,value是一个stacktraceelement实例数组:1 public static map getallstacktraces()使用可以使

继续访问

java线程堆栈信息分析

java堆栈信息分析

继续访问

java 查看堆栈_javap 命令查看堆栈中信息

javap命令是对java文件进行反编译,通过这个命令可以看到堆栈中是怎么压栈和出栈的已经执行顺序,这里简单解释下javap的简单的使用,下面举个例子:题目:i++ 和++i的区别解释:简单点说 这个问题都不难回答,这里就不说了,但是实际上堆栈中区别也是老大了(这里就用到了javap命令), 步骤:1在任意一个盘下面建一个名为Testjava的文件(文件名可以随意命名)代码如下:public

继续访问

java 查看线程堆栈信息_jstack-查看Java进程的线程堆栈信息,锁定高消耗资源代码。

jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:jstack[option]pidjstack[option]executablecorejstack[option][server-id@]remote-hostname-or-ip命令行参数选项说明如下:-llonglistings,会打印出额外的锁信息,在发生死锁时可以用jstack-lpid来观察

继续访问

java堆栈信息怎么看_线程堆栈信息怎么看? - cs_person的个人空间 - OSCHINA - 中文开源技术交流社区

一条线程堆栈信息大概长成下面这个样子:RMI TCP Connection(267865)-17216525" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting for monitor entry [0x00007fd4f8684000]javalangThreadState: BLOCKED (on object m

继续访问

线程堆栈信息怎么看?

一条线程堆栈信息大概长成下面这个样子: RMI TCP Connection(267865)-17216525" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting for monitor entry [0x00007fd

继续访问

java的栈和堆

栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 Java 的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在

继续访问

查看java线程_JAVAJava线程堆栈信息查看

如何获得线程的堆栈信息?线上服务器cpu 100%了,该如何排查问题?1top命令查询哪个pid进程占用cpu高(ps -ef|grep java 获取PID号)2通过 top -Hp pid 可以查看该进程下各个线程的cpu使用情况,获取占用cpu高的线程id3执行命令:printf "%X\n" 线程tid(用于获取占用cpu高的线程id的16进制数)4执行命令:jstack pid

继续访问

kill -3 java_kill -3 PID命令获取java应用堆栈信息

一、应用场景:当linux服务器出现异常情况(响应缓慢,负载持续飙升)并且服务器没有安装对应的包而无法使用jstack等命令时,可以使用linux的kill相关命令打印堆栈信息。命令格式:kill -3 PID二、执行步骤:21、获取java进程的PIDps -ef|grep java结果的第二列数字就是进程对应的pid。22、kill -3 PID(1)如果项目通过Tomcat进行发布(普通

继续访问

jstack 工具 查看JVM堆栈信息

1|0介绍 jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或corefile或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式: jstack [-l] pid 主要分为两个功能: a. 针对活着的进程做本地的或远程的线程dump; b. 针对core文件做线程dump。 jstack用于生成java虚拟机当前时刻的线程快照。线程快照是

继续访问

linux查看java堆栈

1、查看JAVA进程JVM参数 jinfo -flags pid(进程号) -XX:CICompilerCount=2 最大的并行编译数 -XX:InitialHeapSize=16777216 JVM 的初始堆内存大小 -XX:MaxHeapSize=257949696 JVM 的最大堆内存大小 -XX:MaxNewSize=85983232 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=5570560 -XX:OldSize=11206656 2、JVM 查看

继续访问

Linux 如何查看一个进程的堆栈

有两种方法:第一种:pstack 进程ID第二种,使用gdb 然后attach 进程ID,然后再使用命令 thread apply all bt 两种方法都可以列出进程所有的线程的当前的调用栈。不过,使用gdb的方法,还可以查看某些信息,例如局部变量,指针等。不过,如果只看调用栈的话,pstack还是很方便的。

继续访问

JAVA获取堆栈信息

1 通过Throwable获取 StackTraceElement[] stackTrace = new Throwable()getStackTrace(); 2 通过Thread获取 StackTraceElement[] stackTrace = ThreadcurrentThread()getStackTrace();

继续访问

java 查看线程栈大小_基于 Java 线程栈的问题排查

除日志外,还有没有别的方式跟踪线上服务问题呢?或者,跟踪并排除日志里无法发现的问题?方法当然是有的,就是通过现场快照定位并发现问题。我们所说的现场,主要指这两方面:Java 线程栈。线程栈是Java线程工作的快照,可以获得当前线程在做什么;Java 内存堆。堆是JVM的内存快照,可以获取内存分配相关信息。

public class TestPort

{

    public static void main(String[] args)

    {

        Systemoutprintln(getPID("3306"));//得到进程ID,3306是端口名称

        Systemoutprintln(getProgramName(getPID("3306")));//根据进程ID得到映像名称

        killTask(getProgramName(getPID("3306")));//根据映像名称关闭进程

    }

    

    

    // 得到进程ID

    public static String getPID(String port){

        InputStream is = null;

        BufferedReader br = null;

        String pid = null;

        try

        {

            String[] args = new String[]{"cmdexe","/c","netstat -aon|findstr",port};

            is = RuntimegetRuntime()exec(args)getInputStream();

            br = new BufferedReader(new InputStreamReader(is));

            String temp = brreadLine();

            if(temp != null){

                String[] strs = tempsplit("\\s");

                pid=strs[strslength-1];

            }

        }

        catch (IOException e)

        {

            eprintStackTrace();

        }finally{

            try

            {

                brclose();

            }

            catch (IOException e)

            {

                eprintStackTrace();

            }

        }

        return pid;

    }

    

    //根据进程ID得到映像名称

    public static String getProgramName(String pid){

        InputStream is = null;

        BufferedReader br = null;

        String programName = null;

        try

        {

            String[] args = new String[]{"cmdexe","/c","tasklist|findstr",pid};

            is = RuntimegetRuntime()exec(args)getInputStream();

            br = new BufferedReader(new InputStreamReader(is));

            String temp = brreadLine();

            if(temp != null){

                String[] strs = tempsplit("\\s");

                programName=strs[0];

            }

        }

        catch (IOException e)

        {

            eprintStackTrace();

        }finally{

            try

            {

                brclose();

            }

            catch (IOException e)

            {

                eprintStackTrace();

            }

        }

        return programName;

    }

    

    //根据映像名称关闭进程

    public static void killTask(String programName){

        String[] args = new String[]{"Taskkill","/f","/IM",programName};

        try

        {

            RuntimegetRuntime()exec(args);

        }

        catch (IOException e)

        {

            eprintStackTrace();

        }

    }

}

//题主自己看看具体怎么get它的ip地址,好久没有写,不知道了

以上就是关于jstack 分析出线程id 如何找到进程吗全部的内容,包括:jstack 分析出线程id 如何找到进程吗、java 如何获得一个进程的内存使用情况,cpu运行的时间、kill-3生成的线程堆栈怎么查看等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9742947.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存