JVM的性能跳优

首先需要找到需要进行调优的进程。

通过jps -v -l -m 找到我需要调优的进程

其中, -m表示输出传入main方法的参数,

-l表示输出的main类或jar包的名字,

-v表示传入JVM的参数

如果想要看到进程中的线程的堆栈信息,使用jstack,现在我们看6478的运行情况。

用top -Hp 6478 ,输出如下:

找到了最费cpu的时间,58秒。线程号是6479

 jstack在查询的时候,线程号是用16进制表示的,将6479转换为16进制

printf "%x\n" 6479

获取194f后,使用jstack

 

这个耗费58秒cpu的线程是main线程,现在在处于waiting on condition 状态。

一般会出现八种状态:

死锁,deadlock

执行中,Runnable   

等待资源,Waiting on condition

等待获取监视器,Waiting for monitor entry

暂停,Suspended

对象等待中,Object.wait() 或 TIMED_WAITING

阻塞,Blocked

停止,Parked

死锁:一般情况是多个线程相互资源占用,导致无法释放。

阻塞:线程在执行的过程中,所需要的资源长时间等待却一直未能获取到,被线程管理器标识为阻塞状态,也就是等待资源超时的线程。

waiting on condition : 等待资源,等待某个条件的发生。如果大量出现waiting on condition 可能是某个阻塞导致线程无法进行,比如网络阻塞。导致等待读写。

另一情况是sleep,等待睡眠结束,查看代码发现是sleep导致的,可以接受。

waiting for monitor entry和Object.wait(): 需要了解一下临界区,monitor的概念。

临界区:

临界区就是在同一时刻只能有一个任务访问的代码区。通常用这种加锁实现。

synchronized(object){

//代码块

}

monitor:java对象的内部锁。也叫作monitor锁。(理解可能有偏差)

要想访问临界区首先要获取这个锁,每个java对象都有一把锁。

waiting for monitor entry:也就是在等一个临界区,也就是在Entry Set队列中等待。

此时状态一般都是等待状态。

Object.wait():获取了监视器,又用了java.lang.Object.wait()。

也就是当线程获取monitor,也就是锁,但是发现运行的条件没满足,则调用Object(),放弃monitor,同时,机内Wait entry队列中。

如果大量线程在waiting for monitor entry

可能是一个全局锁锁住了大量的线程,导致其他的线程无法进入临界区。

通过查看进程中线程的堆栈信息。发现运行正常。接下来查看堆内存的使用情况,使用jmap。

查看堆内存中的对象数目

 

 

 

 发现有一个对象存活了很多,需要排查一下。

经排查,这个是一个ip库保存对象,有很多个,但是不动态增加了,可以接受。

其实也可以直接使用top,查看耗费资源,如果一段时间内是稳定的,那么程序运行就稳定,也是可以接受的。

接下来查看jvm运行情况:

 

 C 容量 U使用量

E eden    O old   P  Permanent

 

posted @ 2017-02-07 16:48  起个po名真费劲  阅读(291)  评论(0编辑  收藏  举报