如何取得jvm实例的cpujvm 线程占用内存大小

记一次线上Java程序导致服务器CPU占用率过高的问题排除过程 - 简书
下载简书移动应用
写了44367字,被31人关注,获得了109个喜欢
记一次线上Java程序导致服务器CPU占用率过高的问题排除过程
1、故障现象
客服同事反馈平台系统运行缓慢,网页卡顿严重,多次重启系统后问题依然存在,使用top命令查看服务器情况,发现CPU占用率过高。
2、CPU占用过高问题定位
2.1、定位问题进程
使用top命令查看资源占用情况,发现pid为14063的进程占用了大量的CPU资源,CPU占用率高达776.1%,内存占用率也达到了29.8%
[ylp@ylp-web-01 ~]$ top
top - 14:51:10 up 233 days, 11:40,
load average: 6.85, 5.62, 3.97
Tasks: 192 total,
2 running, 190 sleeping,
0 stopped,
%Cpu(s): 97.3 us,
5114392 free,
6907028 used,
4247232 buff/cache
4063228 total,
3989708 free,
73520 used.
8751512 avail Mem
TIME+ COMMAND
11976 S 776.1 29.8 117:41.66 java
2.2、定位问题线程
使用ps -mp pid -o THREAD,tid,time命令查看该进程的线程情况,发现该进程的多个线程占用率很高
[ylp@ylp-web-01 ~]$ ps -mp 14063 -o THREAD,tid,time
%CPU PRI SCNT WCHAN
USER SYSTEM
- 02:05:58
从输出信息可以看出,之间的线程CPU占用率都很高
2.3、查看问题线程堆栈
挑选TID为14065的线程,查看该线程的堆栈情况,先将线程id转为16进制,使用printf "%x\n" tid命令进行转换
[ylp@ylp-web-01 ~]$ printf "%x\n" 14065
再使用jstack命令打印线程堆栈信息,命令格式:jstack pid |grep tid -A 30
[ylp@ylp-web-01 ~]$ jstack 14063 |grep 36f1 -A 30
"GC task thread#0 (ParallelGC)" prio=10 tid=0x0e800 nid=0x36f1 runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f2 runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f3 runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f4 runnable
"GC task thread#4 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f5 runnable
"GC task thread#5 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f6 runnable
"GC task thread#6 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f7 runnable
"GC task thread#7 (ParallelGC)" prio=10 tid=0x0b800 nid=0x36f8 runnable
"VM Periodic Task Thread" prio=10 tid=0x0a8800 nid=0x3700 waiting on condition
JNI global references: 392
从输出信息可以看出,此线程是JVM的gc线程。此时可以基本确定是内存不足或内存泄露导致gc线程持续运行,导致CPU占用过高。所以接下来我们要找的内存方面的问题
3、内存问题定位
3.1、使用jstat -gcutil命令查看进程的内存情况
[ylp@ylp-web-01 ~]$ jstat -gcutil
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
从输出信息可以看出,Eden区内存占用100%,Old区内存占用99.99%,Full GC的次数高达220次,并且频繁Full GC,Full GC的持续时间也特别长,平均每次Full GC耗时6.8秒()。根据这些信息,基本可以确定是程序代码上出现了问题,可能存在不合理创建对象的地方
3.2、分析堆栈
使用jstack命令查看进程的堆栈情况
[ylp@ylp-web-01 ~]$ jstack 14063 &&jstack.out
把jstack.out文件从服务器拿到本地后,用编辑器查找带有项目目录并且线程状态是RUNABLE的相关信息,从图中可以看出ActivityUtil.java类的447行正在使用HashMap.put()方法
Paste_Image.png
3.3、代码定位
打开项目工程,找到ActivityUtil类的477行,代码如下:
Paste_Image.png
找到相关同事了解后,这段代码会从数据库中获取配置,并根据数据库中remain的值进行循环,在循环中会一直对HashMap进行put操作。
查询数据库中的配置,发现remain的数量巨大
Paste_Image.png
至此,问题定位完毕。
么么哒,喜欢就点个赞吧......
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
玩转简书的第一步,从这个专题开始。
想上首页热门榜么?好内容想被更多人看到么?来投稿吧!如果被拒也不要灰心哦~入选文章会进一个队...
· 135853人关注
System.out.println(&Hello world!&);
· 1942人关注
Java是在计算机史上影响深远的编程语言,它是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、...
· 294人关注
么么哒,喜欢就点个赞吧......
选择支付方式:JAVA编程基础(12)
1,获取JVM内存方法:
int kb = 1024;
// 可使用内存
long totalMemory = Runtime.getRuntime().totalMemory() /
// 剩余内存
long freeMemory = Runtime.getRuntime().freeMemory() /
// 最大可使用内存
long maxMemory = Runtime.getRuntime().maxMemory() / 2,获取机器CPU使用率
& & & &lunix 服务器获取方法
public static double[] getCpuUsage(){
double cpuUsed = 0;
double idleUsed = 0.0;
double[] cpuarray = new double[2];
Runtime rt = Runtime.getRuntime();
p = rt.exec(&top -b -n 1&);
BufferedReader in =
in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String str =
int linecount = 0;
while ((str = in.readLine()) != null) {
linecount++;
if (linecount == 3) {
String[] s = str.split(&%&);
String idlestr = s[3];
String idlestr1[] = idlestr.split(& &);
idleUsed = Double.parseDouble(idlestr1[idlestr1.length-1]);
cpuUsed = 100-idleU
cpuarray[0]=cpuU
cpuarray[1]=idleU
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (Exception e) {
// TODO: handle exception
}// call &top& command in linux
} window服务器获取方法
* 获得CPU使用率.
* @return 返回cpu使用率
* @author GuoHuang
private static double getCpuRatioForWindows() {
String procCmd = System.getenv(&windir&)
+ &\\system32\\wbem\\wmic.exe process get Caption,CommandLine,&
+ &KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount&;
// 取进程信息
long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));
Thread.sleep(CPUTIME);
long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));
if (c0 != null && c1 != null) {
long idletime = c1[0] - c0[0];
long busytime = c1[1] - c0[1];
return Double.valueOf(
PERCENT * (busytime) / (busytime + idletime))
.doubleValue();
return 0.0;
} catch (Exception ex) {
ex.printStackTrace();
return 0.0;
}参考链接:
http://write.blog.csdn.net/postedit
/blog/1299958
http://blog.csdn.net/longne/article/details/4518378& 这链接包含各类JVM信息的方法
http://blog.csdn.net/chenzhanhai/article/details/6231789& &这链接包含硬盘使用方法
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:10195次
排名:千里之外
原创:23篇
(5)(2)(3)(1)(5)(3)(2)(3)(3)如何取得jvm实例的cpu占用_百度知道

我要回帖

更多关于 jvm实例 的文章

 

随机推荐