java cup使用率超高的问题解决

本文介绍了一种通过TOP命令和jstack工具定位导致CPU占用率异常升高的Java进程的方法。首先利用TOP命令找出消耗CPU资源最多的进程,记录下其PID及线程号并转换成十六进制,再使用jstack工具获取指定PID的Java进程详细信息,最终通过分析日志文件定位到具体的代码行。

1、TOP命令,查询消耗CPU高的进程号 PID,并记录下来,按下键盘"H"键,记录高消耗线程号,并将改线程号转换为十六进制

2、使用 jstack [pid]  > xx.log 命令打印进程信息,为了定位准确,可以多来几次

3、打开日志文件,找到十六进制的线程信息,可定位到具体类的某一行。

 

演示:

1、查询消耗CPU高的进程号 PID,并记录下来

#top

top - 18:45:29 up 14 days, 23:27,  6 users,  load average: 3.18, 3.08, 2.64

Tasks: 299 total,   1 running, 297 sleeping,   0 stopped,   1 zombie

Cpu(s): 25.7%us,  1.2%sy,  0.3%ni, 72.6%id,  0.1%wa,  0.1%hi,  0.1%si,  0.0%st

Mem:     23641M total,    23388M used,      252M free,      261M buffers

Swap:    24583M total,        0M used,    24583M free,    12252M cached

 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

16511 icore     20   0 3075m 657m  17m S  201  2.8   2859:27 java

 8369 root      20   0  207m 7556 2892 S    3  0.0 798:30.19 runHpiAlarm

22123 load      21   1 92800  19m 8332 S    3  0.1   0:59.40 mdrv

最耗CPU的进程号16511

 

 按下键盘"H"键,记录高消耗线程号,并将改线程号转换为十六进制

top - 18:46:25 up 14 days, 23:28,  6 users,  load average: 3.10, 3.06, 2.66

Tasks: 2722 total,   4 running, 2717 sleeping,   0 stopped,   1 zombie

Cpu(s): 26.0%us,  1.4%sy,  0.4%ni, 71.4%id,  0.8%wa,  0.0%hi,  0.0%si,  0.0%st

Mem:     23641M total,    23395M used,      245M free,      261M buffers

Swap:    24583M total,        0M used,    24583M free,    12256M cached

 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

19691 icore     20   0 3075m 657m  17m R  100  2.8   1419:59 java

19690 icore     20   0 3075m 657m  17m R  100  2.8   1419:58 java

 8370 root      20   0  207m 7556 2892 S    2  0.0 497:56.23 runHpiAlarm

 8408 root      20   0  207m 7556 2892 S    1  0.0 299:23.67 runHpiAlarm

 

线程号:19691 、19690 转换为十六进制为:0x4ceb 、0x4cea

 

2、使用 jstack [pid]  > xx.log 命令打印进程信息

#jstack 16511 > 1.log

#jstack 16511 > 2.log

#jstack 16511 > 3.log

 

3、打开日志文件,找到两个线程信息,如下

"Thread-77" prio=10 tid=0x00007f58d4041800 nid=0x4ceb runnable [0x00007f58d175f000]
   java.lang.Thread.State: RUNNABLE
 at com.huawei.iiss.upadapter.common.oprindex.thread.OprUserIndexThread.run(OprUserIndexThread.java:61)
 at java.lang.Thread.run(Thread.java:662)

"Thread-76" prio=10 tid=0x00007f58d4a43800 nid=0x4cea runnable [0x00007f58bd066000]
   java.lang.Thread.State: RUNNABLE
 at com.huawei.iiss.upadapter.common.oprlog.thread.SaveOprLogThread.run(SaveOprLogThread.java:80)
 at java.lang.Thread.run(Thread.java:662)

 

找到以上红色信息,已经定位到JAVA具体代码,产看代码,发现死循环。。。速度改之

 

附:TOP命令中需要关注的值:
(1)load average:此值反映了任务队列的平均长度;如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高
(2)%us:用户CPU时间百分比;如果此值过高,可能是代码中存在死循环、或是频繁GC等
(3)%sy:系统CPU时间百分比;如果此值过高,可能是系统线程竞争激烈,上下文切换过多,应当减少线程数
(4)%wa:等待输入、输出CPU时间百分比;如果此值过高,说明系统IO速度过慢,CPU大部分时间都在等待IO完成
(5)%hi:硬件中断CPU百分比;当硬件中断发生时,CPU会优先去处理硬件中断;比如,网卡接收数据会产生硬件中断
(6)swap used:被使用的swap;此值过高代表系统因为内存不足在进行频繁的换入、换出操作,这样会影响效率,应增大内存量
(7)%CPU:进程使用CPU的百分比;此值高表示CPU在进行无阻塞运算等

在处理循环导致的CPU占用过高的问题时,优化方法通常围绕减少不必要的计算、合理利用等待时间和引入异步机制展开。以下是一些具体的优化策略: ### 合理使用等待时间 在循环中频繁执行无意义的操作会显著增加CPU负载。可以通过在循环体内引入适当的等待时间(如`Thread.sleep()`)来降低CPU利用率。例如,在轮询队列或检查条件时,可以在每次循环结束时短暂休眠,从而避免持续占用CPU资源。 ```java while (conditionNotMet) { // 执行检查或操作 Thread.sleep(10); // 等待10毫秒后再继续下一次循环 } ``` 这种做法可以有效减少CPU的空转时间,同时对整体性能影响较小[^3]。 ### 使用阻塞式数据结构 当循环用于从队列中获取数据时,优先选择支持阻塞操作的数据结构,如Java中的`LinkedBlockingQueue`。相比通过`poll()`不断尝试获取元素的方式,使用`take()`方法能够在队列为空时自动阻塞线程,直到有新数据到达。这种方式可以显著减少因频繁轮询而导致的CPU消耗。 ```java T take = blockingQueue.take(); // 阻塞直到有数据可用 ``` 如果需要批量处理数据,可以在单次获取后进行多次非阻塞的`poll()`操作,并设置合理的超时时间以避免长时间等待。 ```java long current = System.currentTimeMillis(); List<T> data = new ArrayList<>(); T take = blockingQueue.take(); data.add(take); while (data.size() < 5000 && System.currentTimeMillis() - current < 5000) { T take1 = blockingQueue.poll(); if (take1 != null) { data.add(take1); } } ``` 这样的实现方式既保证了高效的数据获取,又避免了过度消耗CPU资源[^2]。 ### 异步与并发优化 对于涉及多任务处理的场景,可以通过异步编程模型和并发控制手段来降低CPU压力。例如,将部分任务卸载到后台线程中执行,或者使用线程池管理多个工作线程,确保系统不会因为过多的线程切换而陷入性能瓶颈。 此外,合理调整进程或线程的优先级,有助于操作系统更有效地分配CPU资源,特别是在高并发环境下。通过设置关键任务的优先级高于非关键任务,可以在一定程度上缓解CPU过载的问题[^1]。 ### 缓存与减少重复计算 在某些情况下,循环可能重复执行相同的计算或网络请求。为了避免这种情况,可以引入本地缓存机制,将已经计算过的值或远程获取的数据存储起来,下次直接使用缓存结果,减少不必要的开销。 例如,在高频请求场景中,使用本地缓存可以显著降低对网络IO的依赖,从而减轻CPU负担[^2]。 ### 总结 针对循环引起的CPU占用过高问题,主要优化方向包括:引入合理的等待机制、使用阻塞式数据结构、采用异步与并发控制、以及利用缓存减少重复计算。这些方法能够有效降低CPU利用率,同时保持程序的功能完整性和响应能力。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值