java程序很卡怎么排查_java 性能问题排查

cpu占用率过高

1) 首先能过top查看cpu过高的pid,而后通过ps -ef |grep pid查看进程的详细信息。

2) 接着查看每个线程占用的cpu占用率,ps -mp pid -o THREAD,tid,time | sort -rn

或者 通过 top -H -p pid

3) 转换,而后通过比较查看哪个占用过高, 其次将需要的线程ID转换为16进制格式:printf "%x\n" tid

得。

4)  jstack pid |grep tid -A 30   ,jstack 可以查看某个进程的当前线程栈运行情况。根据这个命令的输出可以定位某个进程的所有线程的当前运行状态、运行代码,以及是否死锁等等。

5) 最后就根据得到的信息分析 代码,看哪块会出现问题 。

实战

今天出现了一个问题,集成代码上线后,系统卡死,无法访问,初看日志也没有问题,而后top查看,cpu果然占用100%+;

而后根据如上操作,找到线程id,而后jstack 查看 ,dump信息如下,原来是syslog 出现了问题。

Thread 9099: (state = IN_VM)

- java.net.PlainDatagramSocketImpl.datagramSocketCreate() @bci=0 (Compiled frame; information may be imprecise)

- java.net.AbstractPlainDatagramSocketImpl.create() @bci=15, line=83 (Compiled frame)

- java.net.DatagramSocket.createImpl() @bci=61, line=342 (Compiled frame)

- java.net.DatagramSocket.() @bci=56, line=199 (Compiled frame)

- UDPTest.send() @bci=31, line=35 (Compiled frame)

原生 系统中是有日志记录的,因为项目需求,需要将日志上报syslog服务器,因此需要在记录日志的地方,在调一个syslog的接口,从dump发现,syslog出了问题。但是调用syslog的过程的代码,没发现什么异常。接着我们就去查看syslog的源码,发现确实有问题,如下send方法内形成死循环。现在解决方案就明确了。如果在send异常时,var5 并没有任何变化。如果socket一直异常,则会无限循环。并没有按照设定的值重试。

byte var5 = 0;

while(var5 != -1 && var5 < this.netSyslogConfig.getWriteRetries() + 1) {

try {

this.socket.send(var4);

var5 = -1;

} catch (IOException var7) {

if(var5 == this.netSyslogConfig.getWriteRetries() + 1) {

throw new SyslogRuntimeException(var7);

}

}

}

内存占用过高( 堆 )

1)一般内存分析 使用 jdk自带 的 jmap  jhat

jps -ml //查看pid

jmap -heap 9142 // 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.

jmap -histo:live 9142 |head  -n 20

jmap -F -dump:format=b,file=test.bin 14424

jhat test.bin

访问 http://localhost:7000

也可通过

2) 设置虚拟机参数为:-Xmx40m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:\Java\dump

然后用 jprofile  工具分析 内存 dump文件

通常我们在开发中经常遇到的OutOfMemoryError 有 PermGen space(永久代)  Javaheap space(堆

Java内存模型是描述Java程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节。

在Java虚拟机中,内存分为三个代:新生代(New)、老生代(Old)、永久代(Perm)。

(1)新生代New:新建的对象都存放这里

(2)老生代Old:存放从新生代New中迁移过来的生命周期较久的对象。新生代New和老生代Old共同组成了堆内存。

(3)永久代Perm:是非堆内存的组成部分。主要存放加载的Class类级对象如class本身,method,field等等。

如果出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:

(1)Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。

(2)代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。

如果出现java.lang.OutOfMemoryError: PermGen space,说明是Java虚拟机对永久代Perm内存设置不够。

一般出现这种情况,都是程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。

当遇到  heap space异常,时,要通过分析代码,减少不必要的对象创建,同时避免内存泄漏。

1)top 查看占用率用的pid

2)    jmap -histo:live [pid] > result.log  ,然后分析具体的对象数目和占用内存大小,从而定位代码。

如下 一般占用较高的 constMethodKlass、methodKlass、constantPoolKlass 这些类信息。而遇到 问题的时候 我们应该重点分析 数组,集合,类等占据大量内存的类。

11931d27f9ecadbe828c8430852dd9ce.png

http://www.ibm.com/developerworks/cn/java/j-lo-performance-tuning-practice/

http://blog.csdn.net/blade2001/article/details/9066001

http://www.cnblogs.com/chy2055/p/5124040.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值