0


【性能优化】CPU利用率飙高与内存飙高问题

📫作者简介:小明java问道之路2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

🏆 2022博客之星TOP3 | CSDN博客专家 | 后端领域优质创作者 | CSDN内容合伙人

🏆 InfoQ(极客邦)签约作者、阿里云专家 | 签约博主、51CTO专家 | TOP红人、华为云享专家

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~


🍅 文末获取联系 🍅 👇🏻 精彩专栏推荐订阅收藏 👇🏻
专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

🔥Redis从入门到精通与实战🔥

Redis从入门到精通与实战

围绕原理源码讲解Redis面试知识点与实战

🔥MySQL从入门到精通🔥

MySQL从入门到精通
全面讲解MySQL知识与企业级MySQL实战
🔥计算机底层原理🔥

深入理解计算机系统CSAPP

以深入理解计算机系统为基石,构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

🔥数据结构与企业题库精讲🔥

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

🔥互联网架构分析与实战🔥

企业系统架构分析实践与落地

行业最前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

互联网金融公司的防资损方法论、代码与实践

🔥Java全栈白宝书🔥

精通Java8与函数式编程

本专栏以实战为基础,逐步深入Java8以及未来的编程模式

深入理解JVM

详细介绍内存区域、字节码、方法底层,类加载和GC等知识

深入理解高并发编程

深入Liunx内核、汇编、C++全方位理解并发编程

Spring源码分析

Spring核心七IOC/AOP等源码分析

MyBatis源码分析

MyBatis核心源码分析

Java核心技术

只讲Java核心技术

本文导读

本文对CPU利用率飙高问题,内存飙高问题进行剖析。主要内容有CPU利用率飙高定位步骤、CPU飙高的原因与解决;内存飙高定位步骤以及内存飙高故障分析及解决。

一、CPU利用率飙高问题

1、CPU利用率飙高定位步骤

当cpu经常飙升到100%的使用率,需要定位到具体是哪个线程在占用,定位问题的步骤如下(linux系统):

1、使用top命令常看当前服务器中所有进程(jps命令可以查看当前服务器运行java进程),找到当前cpu使用率最高的进程,获取到对应的pid;

2、然后使用top -Hp pid,查看该进程中的各个线程信息的cpu使用,找到占用cpu高的线程pid。

3、使用jstack pid打印它的线程信息,通过jstack命令打印的线程号和通过top -Hp打印的线程号进制不一样,需要进行转换才能进行匹配,jstack中的线程号为16进制,而top -Hp打印的是10进制。

使用** jastack 命令分析线程信息的时候需要关注线程对应的运行状态**:runnable代表当前线程正在运行,waiting代表当前线程正在等待,该状态需要进行特殊关注wait fot 后面的线程号,因为如果当前处于waiting状态的程序长时间处于等待状态,那么就需要知道它在等待哪个线程结束,也就是wait for后面的线程号,然后根据线程号找到对应的线程,去查看当前线程有什么问题。

2、CPU飙高的原因

1、无限循环或死循环:程序中存在错误的循环结构,导致程序一直在循环执行,从而消耗大量的CPU资源。

2、复杂的算法和计算:程序中执行复杂的算法、大规模的数据处理或者需要大量计算的操作可能导致CPU占用过高。

2、频繁的IO操作:如果程序频繁地进行文件读写、网络通信等IO操作,可能会导致CPU占用增加。

3、线程问题:多线程程序中,线程可能因为竞争条件、死锁、阻塞等问题导致CPU占用过高。

4、内存问题:内存泄漏或内存占用过高可能导致Java虚拟机频繁进行垃圾回收,从而增加CPU负担。

5、不合理的资源管理:没有正确释放或管理资源,如打开的文件、数据库连接等,可能导致CPU占用过高。

6、第三方库或框架问题:使用的第三方库、框架或组件可能存在性能问题,导致程序CPU占用增加。

7、并发问题:不正确的并发控制或同步机制可能导致竞争条件和性能问题。

8、缓存问题:缓存未有效利用,导致程序频繁地从内存或磁盘读取数据,增加了CPU负担。

9、频繁的异常处理:频繁的异常处理可能会导致CPU占用过高,因为异常处理可能会涉及昂贵的堆栈跟踪等操作。

3、CPU飙高的解决方法

1、优化代码:检查代码(code review),优化算法、循环和IO操作,减少CPU负担。

2、线程管理:确保多线程程序中的线程正确管理,避免竞争条件和死锁。

3、内存管理:检查内存泄漏,确保释放不再使用的内存。

4、使用合适的工具:使用性能分析工具来检测CPU占用过高的具体位置和原因。

二、内存飙高问题

内存飙高一般都是堆中对象无法回收造成,因为java中的对象大部分存储在堆内存中。其实也就是常见的oom问题(Out Of Memory)。

查看内存状态的命令(top、free、vmstat,sar,/proc/meminfo)

导致内存不足的三个原因进行占用太高、缓存占用过高没有进行释放、内存泄漏和内存溢出导致内存不足

1、内存飙高定位步骤

1.jinfo pid,可以查看当前进行虚拟机的相关信息列举出来

2.jstat -gc pid ms,多长毫秒打印一次gc信息,打印信息如下,里面包含gc测试,年轻代/老年带gc信息等:

3.jmap -histo pid | head -20,查找当前进程堆中的对象信息,jmap -dump:format=b,file=xxx pid,可以生成堆信息的文件,但是这个命令不建议在生产环境使用,因为当内存较大时,执行该命令会占用大量系统资源,甚至造成卡顿。

在项目启动时添加下面的命令,在发生oom时自动生成堆信息文件:-XX:+HeapDumpOnOutOfMemory。如果需要在线上进行堆信息分析,如果当前服务存在多个节点,可以下线一个节点,生成堆信息,或者使用第三方工具,阿里的arthas。

2、内存飙高故障分析及解决

2.1、进程占用太多的内存

原因:每当对磁盘进行读写操作时,都会先对缓存进行操作,因为缓存是需要消耗内存的,虽然缓存中的内存会自动释放,但是只有当物理空闲内存不够的时候,缓存中才会释放一些内存出来,释放的也仅仅是够用,不会全部释放。

解决办法:使用top命令查看哪个进程占用太多,进行内存排序,kill掉

2.2、缓存占用过高导致内存不足

同进程占用太多的内存处理

2.3、内存泄漏和内存溢出

内存泄漏:程序在申请内存后,无法释放,会导致内存空间不足。

内存溢出:程序申请内存时,没有足够的空间供其使用,出现内存溢出。(解决:检查错误日志,修改JVM启动参数,增加内存,)

内存溢出的原因:内存中加载的数据过于庞大,如一次从数据库读取过多的数据,内存供给不足,导致内存溢出;集合类中有对对象的引用,使用完后未清空,使得JVM(运行java代码的容器,相当于一台java虚拟机)不能回收;代码中存在死循环或循环产生过多重复的对象实体;启动参数内存设定的过小。

总结

本文对CPU利用率飙高问题,内存飙高问题进行剖析。主要内容有CPU利用率飙高定位步骤、CPU飙高的原因与解决;内存飙高定位步骤以及内存飙高故障分析及解决。


本文转载自: https://blog.csdn.net/FMC_WBL/article/details/134587305
版权归原作者 小明java问道之路 所有, 如有侵权,请联系我们删除。

“【性能优化】CPU利用率飙高与内存飙高问题”的评论:

还没有评论