【性能调优-实例演示】CPU爆了怎么定位问题--》调试指令性能分析工具

news/2024/11/25 0:55:28/

性能调优

定位生产性能问题

生产环境,CPU Memory 告警

  1. top:找出占CPU比较高的进程${pid}(内存增长,CPU居高不下)
  2. top -Hp ${pid}:显示所有线程的CPU占比,观察进程中的线程,找出哪个线程CPU和内存占比高
  3. jps ${pid}定位具体java进程
  4. jstack 定位线程状况,重点关注:WAITING BLOCKED。 jstack能检查到死锁的存在,并显示哪些线程发生了死锁;
    在这里插入图片描述

1、是否有死锁:
waiting on <0x0000000088ca3310> (a java.lang.Object)
假如有一个进程中100个线程,很多线程都在waiting on ,一定要找到是哪个线程持有这把锁
怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE。
2、根据线程编号,用jstack查看线程的调用栈信息,对比看是哪个线程一直在占用CPU。

  1. 若是VM线程,那就是一直在FGC,若是频繁FGC,需要看是否正常回收(回收不掉?内存泄露)
  2. 若是业务线程,则查看业务代码问题
  1. jinfo ${pid} 查看线程信息
  2. jstat -gc 动态观察gc情况 / 阅读GC日志发现频繁GC / arthas观察 / jconsole/jvisualVM/ Jprofiler(最好用)

jstat -gc ${pid} 500 : 每个500个毫秒打印GC的情况.

  1. jmap - histo 4655 | head -20,jmap主要被用来分析堆内存的工具,查找有多少对象产生

若是压测环境,可以直接用图形界面工具来分析(MAT/jhat/jvisualvm/arthas);
若是生产环境,线上系统,内存特别大,jmap执行期间会对进程产生很大影响,甚至卡顿(电商不适合),则用cmdline arthas 或以下步骤:

  • 提前设置好启动参数 -XX:HeapDumpOnOutOfMemoryError 当OOM内存爆了,就生成堆存储文件
  • 做负载均衡,把某一台机摘除流量后,再分析(或把流量复制一份到备份机,然后对备份机进行分析)
  • 使用TCP copy命令把流量复制并同时打到生产环境和测试环境,在测试环境做性能分析和观察
  • 在压测环境分析
  • 堆存储文件分析工具:MAT/jhat/jvisualvm
  • https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html
    jhat -J-mx512M xxx.dump
    http://192.168.17.11:7000
    拉到最后:找到对应链接
    可以使用OQL查找特定问题对象
  1. jmap - histo 4655 | head -20,查找有多少对象产生

工具篇

分析HeapDump文件

jconsole远程连接

  1. 程序启动加入参数:

    java -Djava.rmi.server.hostname=192.168.17.11 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11111 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false XXX
    
  2. 如果遭遇 Local host name unknown:XXX的错误,修改/etc/hosts文件,把XXX加入进去

    192.168.17.11 basic localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    
  3. 关闭linux防火墙(实战中应该打开对应端口)

    service iptables stop
    chkconfig iptables off #永久关闭
    
  4. windows上打开 jconsole远程连接 192.168.17.11:11111

jvisualvm远程连接

https://www.cnblogs.com/liugh/p/7620336.html (简单做法)

arthas在线排查工具

  • 为什么需要在线排查?
    在生产上我们经常会碰到一些不好排查的问题,例如线程安全问题,用最简单的threaddump或者heapdump不好查到问题原因。为了排查这些问题,有时我们会临时加一些日志,比如在一些关键的函数里打印出入参,然后重新打包发布,如果打了日志还是没找到问题,继续加日志,重新打包发布。对于上线流程复杂而且审核比较严的公司,从改代码到上线需要层层的流转,会大大影响问题排查的进度。
  • jvm观察jvm信息
  • thread定位线程问题
  • dashboard 观察系统情况
  • heapdump + jhat分析
  • jad反编译
    动态代理生成类的问题定位
    第三方的类(观察代码)
    版本问题(确定自己最新提交的版本是不是被使用)
  • redefine 热替换
    目前有些限制条件:只能改方法实现(方法已经运行完成),不能改方法名, 不能改属性
    m() -> mm()
  • sc - search class
  • watch - watch method
  • 没有包含的功能:jmap

常见问题常见的问题有:

CPU异常高,甚至到100%

https://www.cnblogs.com/python-django-spid/p/16480423.html
思路:top 、top -Hp 查看使用CPU高的进程

进程一般存在7种基础状态:D-不可中断睡眠、R-可执行、S-可中断睡眠、T-暂停态、t-跟踪态、X-死亡态、Z-僵尸态。
D、S:SLEEP态进程不会占用任何CPU资源。
T、t、Z:暂停态、僵尸态 进程会释放所有占用资源。

user(us),代表用户态CPU时间
nice(ni),代表低优先级用户态时间
system(sys),代表内核态CPU时间
idle(id),代表空闲时间,注意不包括等待IO时间
iowait(wa),表示等待IO的CPU时间
irq(hi),代表处理硬中断的CPU时间
softirq(si),代表处理软中断的CPU时间
steal(st),代表当系统运行在虚拟机的时候,被其他虚拟机占用的CPU时间
guest(guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间
guest_nice(gnice),代表以低优先级运行虚拟机的时间
在这里插入图片描述

IOwait过高

JVM进程Hang

https://mp.weixin.qq.com/s/7SHlfonUEW8oWx_IAjuYRw

OOM(内存溢出)

内存泄露

频繁GC

示例

分析过程:

  1. top 找出占CPU高的进程 -->15856

  2. top -Hp 找出进程占CPU高的线程

  3. jps 列出本地或者远程主机上的所有JVM进程。(jps -lm 显示主类的全限定包名或者jar包的全路径名)

  4. jstack 主要JVM进程的线程栈信息:jstack 15856–》查看到没有死锁 WAITING BLOCKED
    在尾部看到有VM GC线程

  5. jmap -heap 15856 分代查看对内存使用情况
    新生代使用的少,老年代使用90%!
    在这里插入图片描述

在这里插入图片描述
jmap -histo 15856,查看堆内存直方图
查看堆内存直方图
jmap -dump:live,format=b,file=helen.hprof 15856,将java heap信息dump成hprof格式的二进制文件,子选项live被指定的时候,仅仅那些存活的堆内存中对象才会被dump出来。被dump出来的文件可以通过__jhat__工具查看

  1. jhat helen.hprof
    执行命令,分析完后会启动7000端口
    在这里插入图片描述
    访问http://localhost:7000/
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. Java自带工具jvisualVM.exe,分析hprof文件
    在这里插入图片描述
package com.vip.fcs.gc;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** 从数据库中读取信用数据,套用模型,并把结果进行记录和传输*/public class T15_FullGC_Problem01 {private static class CardInfo {BigDecimal price = new BigDecimal(0.0);String name = "张三";int age = 5;Date birthdate = new Date();public void m() {}}private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50,new ThreadPoolExecutor.DiscardOldestPolicy());public static void main(String[] args) throws Exception {executor.setMaximumPoolSize(50);for (;;){modelFit();Thread.sleep(100);}}private static void modelFit(){List<CardInfo> taskList = getAllCardInfo();taskList.forEach(info -> {// do somethingexecutor.scheduleWithFixedDelay(() -> {//do sth with infoinfo.m();}, 2, 3, TimeUnit.SECONDS);});}private static List<CardInfo> getAllCardInfo(){List<CardInfo> taskList = new ArrayList<>();for (int i = 0; i < 100; i++) {CardInfo ci = new CardInfo();taskList.add(ci);}return taskList;}
}

http://www.ppmy.cn/news/1001366.html

相关文章

ChatGPT及其工作原理;OpenAI申请注册商标GPT-5,引发关注

&#x1f989; AI新闻 &#x1f680; OpenAI申请注册商标GPT-5&#xff0c;引发关注 摘要&#xff1a;OpenAI已在上月18日申请注册商标GPT-5&#xff0c;显示该模型将提供文本生成、自然语言理解、语音转录、翻译、分析等功能。此前OpenAI曾表示尚未开始训练GPT-4的后继者GPT…

应用案例|基于3D视觉的高反光金属管件识别系统解决方案

Part.1 项目背景 在现代制造业中&#xff0c;高反光金属管件的生产以及质量的把控是一个重要的挑战。传统的2D视觉系统常常难以准确地检测和识别高反光金属管件&#xff0c;因为它们的表面特征不够明显&#xff0c;容易受到光照和阴影的干扰。为了应对这个问题&#xff0c;基于…

Scratch 之 “2000年至今的天数”积木 的用法

2000年至今的天数 看起来&#xff0c;这块积木好像没有什么用&#xff0c;2000年还是固定的一个值&#xff0c;不能输入。点一下它&#xff0c;可以看到返回了一个小数位数特别多的数。 但实际上&#xff0c;这块积木有着非常多的作用。在很多自制积木包中都用到了这块积木。…

Oneway接口

在软件开发中&#xff0c;Oneway接口是指一种仅支持单向方法调用的接口。也就是说&#xff0c;调用方发送请求后&#xff0c;不需要等待服务方的响应&#xff0c;调用方直接继续执行后续操作。 Oneway接口的作用主要是在某些场景下提高了系统的性能和响应速度。因为Oneway接口…

网站架构演变、LNP+Mariadb数据库分离、Web服务器集群、Keepalived高可用

day02 day02深入理解程序的数据存储验证配置NFS服务器配置代理服务器配置名称解析服务器配置 深入理解程序的数据存储 程序将文字数据保存到数据库中程序将非文字数据&#xff08;如图片、视频、压缩包等&#xff09;保存到相应的文件目录中 验证 发一篇文章&#xff0c;文…

【MySQL】删除重复数据,先进先删

系列文章 C#底层库–MySQLBuilder脚本构建类&#xff08;select、insert、update、in、带条件的SQL自动生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库操作辅助类&#xff08;推荐阅读&#xff0…

sqlite 踩坑

内存数据库 强制SQLite数据库单纯的存在于内存中的常用方法是使用特殊文件名“ &#xff1a;memory&#xff1a; ” db QSqlDatabase::addDatabase("QSQLITE", "MEMORY"); db.setDatabaseName(":memory:"); 调用此接口完成后&#xff0c;不…

一个3年Android的找工作记录

作者&#xff1a;Petterp 这是我最近 1个月 的找工作记录&#xff0c;希望这些经历对你会有所帮助。 有时机会就像一阵风&#xff0c;如果没有握住&#xff0c;那下一阵风什么时候吹来&#xff0c;往往是个运气问题。 写在开始 先说背景: 自考本&#xff0c;3年经验&#xff0…