jvm调优--查找最耗CPU的代码

1.场景

今天在公司用mvn编译的时候,出现机器卡死的情况,让我深深的反省了一下。

[java]viewplaincopyprint?

01.../apache-maven-3.0.5/bin/mvn-Dhadoop.version=0.20.2-cdh3u5-DskipTestscleanpackage

../apache-maven-3.0.5/bin/mvn-Dhadoop.version=0.20.2-cdh3u5-DskipTestscleanpackage

这样的编译会出现问题,编译不下去,因为maven需要设置一下jvm参数才行。

[java]viewplaincopyprint?

01.exportMAVEN_OPTS="-Xmx1g-XX:MaxPermSize=512M-XX:ReservedCodeCacheSize=512m"

exportMAVEN_OPTS="-Xmx1g-XX:MaxPermSize=512M-XX:ReservedCodeCacheSize=512m"

-Xmx1g->JVM最大允许分配的堆内存,按需分配

-XX:MaxPermSize->JVM永久带的最大内存,按需分配

-XX:ReservedCodeCacheSize->编译器的代码缓存大小

这样一般都会执行下去,但是当机器负载很高的情况下执行这个的话,会出现机器卡死。

2.引子

咨询了下同事,自己查了查资料总结了下,是因为maven本身启动的也是一个jvm程序,像gradle一样,这样的构建都是启动jvm来调用原生的java编译器来进行编译。

maven本身也需要内存来下载依赖,启动自己的插件,来fork进程执行其它的操作。

了解了原因,以后编译大型项目的时候,要先查看下机器的负载,不然很容易会done掉。

3.查找最耗CPU的代码

其实这个查找最耗CPU的代码本不该放在这里,貌似和和上面的场景无关,但是我还是想写在这里,权且当个笔记吧。

我在ubuntu12.04上启动了一个itellijideal这个IDE,它也启动了一个jvm。

首先,查看一下系统的负载情况,这里可以看到PID为9764的消耗的CPU和MEM最多,command是java,其实就是我的intellij。

[java]viewplaincopyprint?

01.top

top

第二步,查看一下9764这个进程的子进程。

[java]viewplaincopyprint?

01.top-p9764-H

top-p9764-H

发现pid为9791的子进程(我理解为线程)最耗费资源,当然还有一个9924(略)。

第三步,将这个pid转换为16进制,结果为263f

[java]viewplaincopyprint?

01.printf"%x\n"9791

printf"%x\n"9791[java]viewplaincopyprint?

01.263f

263f

第四步,用jstack打印出父进程的栈,从而找到pid为263f的这个线程的栈信息。

[java]viewplaincopyprint?

01.jstack9764|grep263f-A30

jstack9764|grep263f-A30

可以看出:

1.java的线程池运行任务比较耗费资源。

2.事件轮询和派发比较耗费资源。

总结:

1.以后用maven编译要充分考虑机器的负载,和maven编译的目标所需要的资源情况。

2.排查最耗费系统资源的java代码:

2.1找出top中最耗费系统资源的PID

2.2找出这个PID的子进程最耗费资源的PID

2.3将PID转换为16进制

2.4用jstackpid|grep子PID十六进制-A30来找出这个片段。

原创,转载请注明出处http://blog.csdn.net/oopsoom/article/details/23917699

jvm

相关推荐