`

JVM问题排查

 
阅读更多

一、CPU问题排查

 

1、jstack命令查看线程运行情况

 

1)死锁,Deadlock(重点关注) 

 

2)执行中,Runnable   

 

3)等待获取监视器,Waiting on monitor entry(重点关注),此线程还未进入对象的synchronized的方法,还在Entry Set中等待。

 

"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting for monitor entry [0x00007fd4f8684000]

   java.lang.Thread.State: BLOCKED (on object monitor)

at org.apache.log4j.Category.callAppenders(Category.java:201)

- waiting to lock <0x00000000acf4d0c0> (a org.apache.log4j.Logger)

at org.apache.log4j.Category.forcedLog(Category.java:388)

at org.apache.log4j.Category.log(Category.java:853)

at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:234)

at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:110)

 

4)等待资源,Waiting on condition(重点关注),此线程在等待一个条件的发生,来把自己唤醒,或者调用了sleep方法。此时线程的状态:

          WAITING(parking):一直等待那个条件发生

          TIMED_WAITING(parking或sleeping):定时等待,即使条件不发生,时间到了也可以自己唤醒

          如果发现大量线程处于此状态,并且从线程的堆栈上查看到是正在执行网络读写,这可能是一个网络瓶颈问题或者第三方响应慢的问题

"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2 waiting on condition [0x00007fd4f1a59000]

   java.lang.Thread.State: TIMED_WAITING (parking)

at sun.misc.Unsafe.park(Native Method)

- parking to wait for  <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)

at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)

at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)

at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)

at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)

at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)

at java.lang.Thread.run(Thread.java:662)

 

 

5)等待对象,Object.wait() 或 TIMED_WAITING,此线程已经进入了synchronized的方法,由于某种原因手动调用了对象的wait方法,放弃了Monitor,进入Wait Set队列。

         此时线程状态大致为以下几种:TIMED_WAITING (on object monitor)和 WAITING (on object monitor)。

只有当别的线程在该对象上调用了 notify() 或者 notifyAll() ,“ Wait Set”队列中线程才得到机会去竞争,但是只有一个线程获得对象的 Monitor,恢复到运行态。

 

"RMI RenewClean-[172.16.5.19:28475]" daemon prio=10 tid=0x0000000041428800 nid=0xb09 in Object.wait() [0x00007f34f4bd0000]

   java.lang.Thread.State: TIMED_WAITING (on object monitor)

at java.lang.Object.wait(Native Method)

- waiting on <0x00000000aa672478> (a java.lang.ref.ReferenceQueue$Lock)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)

- locked <0x00000000aa672478> (a java.lang.ref.ReferenceQueue$Lock)

at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:516)

at java.lang.Thread.run(Thread.java:662)

 

6)暂停,Suspended

 

7)阻塞,Blocked(重点关注)  

 

8)停止,Parked

 

二、内存问题排查

 

1、jmap查看堆内存

 

  jmap -heap pid

  jmap -histo:live pid > memory.log   统计所有存活对象的个数,观察那些数量最多的对象,特别是自己写的对象和存放到集合里没有释放的对象

  jmap -dump 导出整个Heap,然后使用工具进行分析,注意看自己写的类的依赖关系,看看是不是使用完没有释放,或者一次性查询过多的数据导致内存溢出

 

 

2、jstat查看虚拟机内存,包括gc情况

 

  jstat -gc pid 1000

  jstat -gcutil pid 1000

  如果Old区的使用情况接近100%,则代表内存不足

  

     S0       S1       E        O          P       YGC     YGCT    FGC    FGCT     GCT   

    54.62   0.00     42.87    43.52      86.24     1792    5.093   33    7.670    12.763

 

S0:新生代的susvivor0区,空间使用率为54..62%

 

S1:新生代的susvivor1区,空间使用率为0.00%(因为还没有执行第二次minor收集)

 

E:eden区,空间使用率42.87%

 

O:旧生代,空间使用率43.52%

 

P:持久带,空间使用率86.24%

 

YGC:minor gc执行次数1792次

 

YGCT:minor gc耗费的时间5.093毫秒

 

FGC:full gc执行次数33

 

FGCT:full gc耗费的时间7.670毫秒

 

GCT:gc耗费的总时间12.763毫秒

 

 

三、网络问题排查

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics