linux下jmap,jstat和jstack使用

刚好用到,转自http://blog.csdn.net/sinat_29581293/article/details/70214436 有空再整理:

先jps -ml

再sudo -u hive /usr/java/latest/bin/jstack 19661(此为进程号) > /tmp/jstack.txt

首先回顾下相关概念:

Java堆和栈的区别

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

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。 
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义: 
int a = 3; 
int b = 3; 
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。 
这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。 
要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

1.jstat

jstat -gcutil pid 5s

每隔5s监控一次内存回收情况

E 代表 Eden 区使用率;
O(Old)代表老年代使用率    ;
P(Permanent)代表永久代使用率;

CCS 压缩使用比例

M 元空间(MetaspaceSize)已使用的占当前容量百分比
YGC(Young GC)代表Minor GC 次数;
YGCT代表Minor GC耗时;
FGC(Full GC)代表Full GC次数;
FGCT(Full GC)代表Full GC耗时;
GCT代表Minor & Full GC共计耗时。

A、 jps(Java Virtual Machine Process Status Tool)

jps主要用来输出JVM中运行的进程状态信息。语法格式如下:

jps [options] [hostid]

如果不指定hostid就默认为当前主机或服务器。

命令行参数选项说明如下:

  1. -q 不输出类名、Jar名和传入main方法的参数

  2.  

    -m 输出传入main方法的参数

  3.  

    -l 输出main类或Jar的全限名

  4.  

    -v 输出传入JVM的参数

比如下面:

  1. [email protected]:/# jps -m -l

  2.  

    2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml

  3.  

    29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat

  4.  

    3149 org.apache.catalina.startup.Bootstrap start

  5.  

    30972 sun.tools.jps.Jps -m -l

  6.  

    8247 org.apache.catalina.startup.Bootstrap start

  7.  

    25687 com.sun.tools.hat.Main -port 9999 dump.dat

  8.  

    21711 mrf-center.jar

B、 jstack

jstack -F pid 检查是否有死锁

jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

  1. jstack [option] pid

  2.  

    jstack [option] executable core

  3.  

    jstack [option] [[email protected]]remote-hostname-or-ip

命令行参数选项说明如下:

  1. -l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况

  2.  

    -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)

jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。

第一步先找出Java进程ID,我部署在服务器上的Java应用名称为mrf-center:

  1. [email protected]:/# ps -ef | grep mrf-center | grep -v grep

  2.  

    root     21711     1  1 14:47 pts/3    00:02:10 java -jar mrf-center.jar

得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid,我这里用第三个,输出如下:

TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用

printf "%x\n" 21742

得到21742的十六进制值为54ee,下面会用到。

OK,下一步终于轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:

  1. [email protected]:/# jstack 21711 | grep 54ee

  2.  

    "PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000]

可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),我找了下我的代码,定位到下面的代码:

[java] view plain copy

  1. // Idle wait
  2. getLog().info("Thread [" + getName() + "] is idle waiting...");
  3. schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting;
  4. long now = System.currentTimeMillis();
  5. long waitTime = now + getIdleWaitTime();
  6. long timeUntilContinue = waitTime - now;
  7. synchronized(sigLock) {
  8. try {
  9. if(!halted.get()) {
  10. sigLock.wait(timeUntilContinue);
  11. }
  12. }
  13. catch (InterruptedException ignore) {
  14. }
  15. }

它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。

C、 jmap(Memory Map)和jhat(Java Heap Analysis Tool)

jmap用来查看堆内存使用状况,一般结合jhat使用。

jmap语法格式如下:

  1. jmap [option] pid

  2.  

    jmap [option] executable core

  3.  

    jmap [option] [[email protected]]remote-hostname-or-ip

如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。

jmap -permstat pid

打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如下图:

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:

  1. [email protected]:/# jmap -heap 21711

  2.  

    Attaching to process ID 21711, please wait...

  3.  

    Debugger attached successfully.

  4.  

    Server compiler detected.

  5.  

    JVM version is 20.10-b01

  6.  

  7.  

    using thread-local object allocation.

  8.  

    Parallel GC with 4 thread(s)

  9.  

  10.  

    Heap Configuration:

  11.  

    MinHeapFreeRatio = 40

  12.  

    MaxHeapFreeRatio = 70

  13.  

    MaxHeapSize      = 2067791872 (1972.0MB)

  14.  

    NewSize          = 1310720 (1.25MB)

  15.  

    MaxNewSize       = 17592186044415 MB

  16.  

    OldSize          = 5439488 (5.1875MB)

  17.  

    NewRatio         = 2

  18.  

    SurvivorRatio    = 8

  19.  

    PermSize         = 21757952 (20.75MB)

  20.  

    MaxPermSize      = 85983232 (82.0MB)

  21.  

  22.  

    Heap Usage:

  23.  

    PS Young Generation

  24.  

    Eden Space:

  25.  

    capacity = 6422528 (6.125MB)

  26.  

    used     = 5445552 (5.1932830810546875MB)

  27.  

    free     = 976976 (0.9317169189453125MB)

  28.  

    84.78829520089286% used

  29.  

    From Space:

  30.  

    capacity = 131072 (0.125MB)

  31.  

    used     = 98304 (0.09375MB)

  32.  

    free     = 32768 (0.03125MB)

  33.  

    75.0% used

  34.  

    To Space:

  35.  

    capacity = 131072 (0.125MB)

  36.  

    used     = 0 (0.0MB)

  37.  

    free     = 131072 (0.125MB)

  38.  

    0.0% used

  39.  

    PS Old Generation

  40.  

    capacity = 35258368 (33.625MB)

  41.  

    used     = 4119544 (3.9287033081054688MB)

  42.  

    free     = 31138824 (29.69629669189453MB)

  43.  

    11.683876009235595% used

  44.  

    PS Perm Generation

  45.  

    capacity = 52428800 (50.0MB)

  46.  

    used     = 26075168 (24.867218017578125MB)

  47.  

    free     = 26353632 (25.132781982421875MB)

  48.  

    49.73443603515625% used

  49.  

    ....

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:

  1. [email protected]:/# jmap -histo:live 21711 | more

  2.  

  3.  

    num     #instances         #bytes  class name

  4.  

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

  5.  

    1:         38445        5597736  <constMethodKlass>

  6.  

    2:         38445        5237288  <methodKlass>

  7.  

    3:          3500        3749504  <constantPoolKlass>

  8.  

    4:         60858        3242600  <symbolKlass>

  9.  

    5:          3500        2715264  <instanceKlassKlass>

  10.  

    6:          2796        2131424  <constantPoolCacheKlass>

  11.  

    7:          5543        1317400  [I

  12.  

    8:         13714        1010768  [C

  13.  

    9:          4752        1003344  [B

  14.  

    10:          1225         639656  <methodDataKlass>

  15.  

    11:         14194         454208  java.lang.String

  16.  

    12:          3809         396136  java.lang.Class

  17.  

    13:          4979         311952  [S

  18.  

    14:          5598         287064  [[I

  19.  

    15:          3028         266464  java.lang.reflect.Method

  20.  

    16:           280         163520  <objArrayKlassKlass>

  21.  

    17:          4355         139360  java.util.HashMap$Entry

  22.  

    18:          1869         138568  [Ljava.util.HashMap$Entry;

  23.  

    19:          2443          97720  java.util.LinkedHashMap$Entry

  24.  

    20:          2072          82880  java.lang.ref.SoftReference

  25.  

    21:          1807          71528  [Ljava.lang.Object;

  26.  

    22:          2206          70592  java.lang.ref.WeakReference

  27.  

    23:           934          52304  java.util.LinkedHashMap

  28.  

    24:           871          48776  java.beans.MethodDescriptor

  29.  

    25:          1442          46144  java.util.concurrent.ConcurrentHashMap$HashEntry

  30.  

    26:           804          38592  java.util.HashMap

  31.  

    27:           948          37920  java.util.concurrent.ConcurrentHashMap$Segment

  32.  

    28:          1621          35696  [Ljava.lang.Class;

  33.  

    29:          1313          34880  [Ljava.lang.String;

  34.  

    30:          1396          33504  java.util.LinkedList$Entry

  35.  

    31:           462          33264  java.lang.reflect.Field

  36.  

    32:          1024          32768  java.util.Hashtable$Entry

  37.  

    33:           948          31440  [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;

class name是对象类型,说明如下:

  1. B  byte

  2.  

    C  char

  3.  

    D  double

  4.  

    F  float

  5.  

    I  int

  6.  

    J  long

  7.  

    Z  boolean

  8.  

    [  数组,如[I表示int[]

  9.  

    [L+类名 其他对象

还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:

jmap -dump:format=b,file=dumpFileName

我一样地对上面进程ID为21711进行Dump:

  1. [email protected]:/# jmap -dump:format=b,file=/tmp/dump.dat 21711     

  2.  

    Dumping heap to /tmp/dump.dat ...

  3.  

    Heap dump file created

dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:

  1. [email protected]:/# jhat -port 9998 /tmp/dump.dat

  2.  

    Reading from /tmp/dump.dat...

  3.  

    Dump file created Tue Jan 28 17:46:14 CST 2014

  4.  

    Snapshot read, resolving...

  5.  

    Resolving 132207 objects...

  6.  

    Chasing references, expect 26 dots..........................

  7.  

    Eliminating duplicate references..........................

  8.  

    Snapshot resolved.

  9.  

    Started HTTP server on port 9998

  10.  

    Server is ready.

然后就可以在浏览器中输入主机地址:9998查看了:

上面红线框出来的部分大家可以自己去摸索下,最后一项支持OQL(对象查询语言)。

D、jstat(JVM统计监测工具)

语法格式如下:

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

vmid是虚拟机ID,在Linux/Unix系统上一般就是进程ID。interval是采样时间间隔。count是采样数目。比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:

  1. [email protected]:/# jstat -gc 21711 250 4

  2.  

    S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   

  3.  

    192.0  192.0   64.0   0.0    6144.0   1854.9   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649

  4.  

    192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649

  5.  

    192.0  192.0   64.0   0.0    6144.0   1972.2   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649

  6.  

    192.0  192.0   64.0   0.0    6144.0   2109.7   32000.0     4111.6   55296.0 25472.7    702    0.431   3      0.218    0.649

要明白上面各列的意义,先看JVM堆内存布局:

可以看出:

  1. 堆内存 = 年轻代 + 年老代 + 永久代

  2.  

    年轻代 = Eden区 + 两个Survivor区(From和To)

现在来解释各列含义:

  1. S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)

  2.  

    EC、EU:Eden区容量和使用量

  3.  

    OC、OU:年老代容量和使用量

  4.  

    PC、PU:永久代容量和使用量

  5.  

    YGC、YGT:年轻代GC次数和GC耗时

  6.  

    FGC、FGCT:Full GC次数和Full GC耗时

  7.  

    GCT:GC总耗时

其他JVM性能调优参考资料:

《Java虚拟机规范》

《Java Performance》

《Trouble Shooting Guide for JavaSE 6 with HotSpot VM》: http://www.oracle.com/technetwork/java/javase/tsg-vm-149989.pdf

《Effective Java》

VisualVM: http://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/

jConsole: http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html

Monitoring and Managing JavaSE 6 Applications: http://www.oracle.com/technetwork/articles/javase/monitoring-141801.html

来自: http://my.oschina.net/feichexia/blog/196575

jstack信息分析

[java] view plain copy

  1. 2017-04-17 17:45:39
  2. Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):
  3. "Attach Listener" daemon prio=10 tid=0x00007f75a4001000 nid=0x947 waiting on condition [0x0000000000000000]
  4. java.lang.Thread.State: RUNNABLE
  5. "LeaseRenewer:[email protected]" daemon prio=10 tid=0x00007f7364f5a000 nid=0x537 waiting on condition [0x00007f713407f000]
  6. java.lang.Thread.State: TIMED_WAITING (sleeping)
  7. at java.lang.Thread.sleep(Native Method)
  8. at org.apache.hadoop.hdfs.LeaseRenewer.run(LeaseRenewer.java:438)
  9. at org.apache.hadoop.hdfs.LeaseRenewer.access$700(LeaseRenewer.java:71)
  10. at org.apache.hadoop.hdfs.LeaseRenewer$1.run(LeaseRenewer.java:298)
  11. at java.lang.Thread.run(Thread.java:745)
  12. "HiveServer2-Handler-Pool: Thread-883126" prio=10 tid=0x00007f73bc016000 nid=0x4e5 waiting on condition [0x00007f7137bba000]
  13. java.lang.Thread.State: TIMED_WAITING (parking)
  14. at sun.misc.Unsafe.park(Native Method)
  15. - parking to wait for  <0x00000006585a35d8> (a java.util.concurrent.SynchronousQueue$TransferStack)
  16. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  17. at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
  18. at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
  19. at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
  20. at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
  21. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
  22. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  23. at java.lang.Thread.run(Thread.java:745)
  24. "IPC Parameter Sending Thread #729" daemon prio=10 tid=0x00007f7364f59000 nid=0x73cc waiting on condition [0x00007f712c302000]
  25. java.lang.Thread.State: TIMED_WAITING (parking)
  26. at sun.misc.Unsafe.park(Native Method)
  27. - parking to wait for  <0x0000000656680e10> (a java.util.concurrent.SynchronousQueue$TransferStack)
  28. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  29. at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
  30. at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
  31. at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
  32. at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
  33. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
  34. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  35. at java.lang.Thread.run(Thread.java:745)
  36. "HiveServer2-Handler-Pool: Thread-882656" prio=10 tid=0x00007f73bc013000 nid=0x497a waiting on condition [0x00007f712cc0b000]
  37. java.lang.Thread.State: TIMED_WAITING (parking)
  38. at sun.misc.Unsafe.park(Native Method)
  39. - parking to wait for  <0x00000006585a35d8> (a java.util.concurrent.SynchronousQueue$TransferStack)
  40. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  41. at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
  42. at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
  43. at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
  44. at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
  45. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
  46. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  47. at java.lang.Thread.run(Thread.java:745)
  48. "qtp931145444-882653" daemon prio=10 tid=0x00007f747401c000 nid=0x3376 waiting on condition [0x00007f7137dbc000]
  49. java.lang.Thread.State: TIMED_WAITING (parking)
  50. at sun.misc.Unsafe.park(Native Method)
  51. - parking to wait for  <0x0000000657459540> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  52. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  53. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
  54. at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:342)
  55. at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:526)
  56. at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:44)
  57. at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
  58. at java.lang.Thread.run(Thread.java:745)
  59. "qtp931145444-882456" daemon prio=10 tid=0x00007f7470001000 nid=0x9600 waiting on condition [0x00007f7133776000]
  60. java.lang.Thread.State: TIMED_WAITING (parking)
  61. at sun.misc.Unsafe.park(Native Method)
  62. - parking to wait for  <0x0000000657459540> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  63. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  64. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
  65. at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:342)
  66. at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:526)
  67. at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:44)
  68. at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
  69. at java.lang.Thread.run(Thread.java:745)
  70. "qtp931145444-882454" daemon prio=10 tid=0x00007f7454005800 nid=0x8ca1 waiting on condition [0x00007f713508f000]
  71. java.lang.Thread.State: TIMED_WAITING (parking)
  72. at sun.misc.Unsafe.park(Native Method)
  73. - parking to wait for  <0x0000000657459540> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  74. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  75. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
  76. at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:342)
  77. at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:526)
  78. at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:44)
  79. at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
  80. at java.lang.Thread.run(Thread.java:745)
  81. "qtp931145444-881328" daemon prio=10 tid=0x00007f746c001800 nid=0x184c waiting on condition [0x00007f713306f000]
  82. java.lang.Thread.State: TIMED_WAITING (parking)
  83. at sun.misc.Unsafe.park(Native Method)
  84. - parking to wait for  <0x0000000657459540> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  85. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  86. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
  87. at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:342)
  88. at org.eclipse.jetty.util.thread.QueuedThreadPool.idleJobPoll(QueuedThreadPool.java:526)
  89. at org.eclipse.jetty.util.thread.QueuedThreadPool.access$600(QueuedThreadPool.java:44)
  90. at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
  91. at java.lang.Thread.run(Thread.java:745)
  92. "pool-68894-thread-1" prio=10 tid=0x00007f73649a1800 nid=0x6d7 waiting on condition [0x00007f7130544000]
  93. java.lang.Thread.State: TIMED_WAITING (parking)
  94. at sun.misc.Unsafe.park(Native Method)
  95. - parking to wait for  <0x00000006c5af6798> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
  96. at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
  97. at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
  98. at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
  99. at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
  100. at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
  101. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
  102. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  103. at java.lang.Thread.run(Thread.java:745)

各状态说明:

New: 当线程对象创建时存在的状态,此时线程不可能执行;

Runnable:当调用thread.start()后,线程变成为Runnable状态。只要得到CPU,就可以执行;

Running:线程正在执行;

Waiting:执行thread.join()或在锁对象调用obj.wait()等情况就会进该状态,表明线程正处于等待某个资源或条件发生来唤醒自己;

Timed_Waiting:执行Thread.sleep(long)、thread.join(long)或obj.wait(long)等就会进该状态,与Waiting的区别在于Timed_Waiting的等待有时间限制;

Blocked:如果进入同步方法或同步代码块,没有获取到锁,则会进入该状态;

Dead:线程执行完毕,或者抛出了未捕获的异常之后,会进入dead状态,表示该线程结束

其次,对于jstack日志,我们要着重关注如下关键信息

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待获取锁

in Object.wait():获取锁后又执行obj.wait()放弃锁

对于Waiting on monitor entry 和 in Object.wait()的详细描述:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 "Active Thread",而其它线程都是 "Waiting Thread",分别在两个队列 " Entry Set"和 "Wait Set"里面等候。在 "Entry Set"中等待的线程状态是 "Waiting for monitor entry",而在 "Wait Set"中等待的线程状态是 "in Object.wait()"

总结:

对于jstack日志,我们要着重关注如下关键信息

Deadlock:表示有死锁

Waiting on condition:等待某个资源或条件发生来唤醒自己。具体需要结合jstacktrace来分析,比如线程正在sleep,网络读写繁忙而等待

Blocked:阻塞

Waiting on monitor entry:在等待获取锁

如果说系统慢,那么要特别关注Blocked,Waiting on condition

如果说系统的cpu耗的高,那么肯定是线程执行有死循环,那么此时要关注下Runable状态。

http://blog.csdn.net/zxh87/article/details/52137335

原文地址:https://www.cnblogs.com/jjj250/p/12091578.html

时间: 2025-01-22 07:11:06

linux下jmap,jstat和jstack使用的相关文章

Linux下Java性能监控

Linux下Java性能监控 一.JVM堆内存使用监控 获取thread dump的3种方法: 1)使用$JAVA_HOME/bin/jcosole中的MBean,到MBean>com.sun.management>HotSpotDiagnostic>操作>dumpHeap中,点击 dumpHeap按钮.生成的dump文件在java应用的根目录下面. 2)jmap -heap 1234 (1234为进程号) 3)cmd ->jvisualvm,远程连接,选择堆Dump生成he

Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算

目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps 命令 top命令 单核情况下Cpu使用率的计算 基本思想 总的Cpu使用率计算 计算方法 某一进程Cpu使用率的计算 计算方法 实验数据 某一线程Cpu使用率的计算 计算方法 实验数据 多核情况下cpu使用率的计算 实验一 描述 数据一 数据二 实验二 描述 数据一 数据二 主要问题 Java 系统

linux下监控jvm 使用的方法

之前一直用jconsole监控jvm,图形界面简单易用,最近因为需要在纯linux下进行操作,所以总结了一下 linux下监控jvm的例子,这次主要用到了jstat工具, 各个参数意义: jstat -class pid:显示加载class的数量,及所占空间等信息. jstat -compiler pid:显示VM实时编译的数量等信息. jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间.其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数

linux下tomcat shutdown后 java进程依旧存在 -- 阿里MetaQ篇

此篇文章描述的症状和上一篇文章一致(即执行tomcat ./shutdown.sh 后,虽然tomcat服务不能正常访问了,但是ps -ef | grep java 后,发现tomcat对应的java进程未随web容器关闭而销毁,进而存在僵尸java进程),但是处理的过程不一致,所有又单开了一篇blog来写. 我在另外一个项目中使用到了阿里的MetaQ消息中间件,然后shutdown tomcat 发现java进程依旧存在,沿用上一篇文章的思路,我最开始以为是本地代码中scheduledExec

Linux下Java线程详细监控和其dump的分析使用----分析Java性能瓶颈

这里对linux下.sun(oracle) JDK的线程资源占用问题的查找步骤做一个小结: linux环境下,当发现java进程占用CPU资源很高,且又要想更进一步查出哪一个java线程占用了CPU资源时,按照以下步骤进行查找: (一):通过[top -p 12377 -H] 查看java进程的有哪些线程的运行情况:       和通过[jstack 12377 > stack.log]生成Java线程的dump详细信息: 先用top命令找出占用资源厉害的java进程id,如图:# top 如上

Linux下java进程CPU占用率高分析方法

Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 1. 通过top命令找到可疑进程PID top - 09:37:18 up 70 days, 16:29, 2 users, load average: 1.13, 1.04, 0.97 Tasks: 105 total, 1 running

Linux下WebSphereV8.5.5.0 安装详细过程

Linux下WebSphereV8.5.5.0 安装详细过程 自WAS8以后安装包不再区别OS,一份介质可以安装到多个平台.只针对Installation Manager 进行了操作系统的区分 ,Websphere产品介质必须通过专门的工具Install Managere安装.进入IBM的官网http://www.ibm.com/us/en/进行下载.在云盘http://yun.baidu.com/share/linkshareid=2515770728&uk=4252782771 中是Linu

10.6 监控io性能 - 10.7 free命令 - 10.8 ps命令 - 10.9 查看网络状态 - 10.10 linux下抓包

- 10.6 监控io性能 - 10.7 free命令 - 10.8 ps命令 - 10.9 查看网络状态 - 10.10 linux下抓包 - 扩展tcp三次握手四次挥手 http://www.doc88.com/p-9913773324388.html  - tshark几个用法:http://www.aminglinux.com/bbs/thread-995-1-1.html  # 10.6 监控io性能 ![mark](http://oqxf7c508.bkt.clouddn.com/b

Linux下的SVN服务器搭建

鉴于在搭建时,参考网上很多资料,网上资料在有用的同时,也坑了很多人 本文的目的,也就是想让后继之人在搭建svn服务器时不再犯错,不再被网上漫天的坑爹作品所坑害,故此总结 /******开始*********/ 系统环境:Centos 6.5 第一步:通过yum命令安装svnserve,命令如下: >yum -y install  subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停止命令运行 若需查看svn安装位置,可以用以下命令: >rpm -ql subve