原因分析(java):CPU内存占用过高 || 程序长时间运行也没有结果

本文介绍如何使用top命令查看CPU负载及进程信息,并通过ps和JVM工具jstack找出导致CPU占用过高的线程。涵盖top命令的基础操作、线程CPU占用率的查找方法以及JVM线程堆栈分析。

基础知识准备

查看CPU信息

 cat /proc/cpuinfo
 cat /proc/cpuinfo|grep 'cpu cores' # cpu的物理核数
 cat /proc/cpuinfo|grep 'processor' # 查看逻辑核标识,一般从0开始

在这里插入图片描述

top指令

在这里插入图片描述

  • load average: 0.03, 0.06, 0.06 负载均衡值,三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值
  • CPU(s)是系统所有用户进程占用整个CPU的平均值,由于每个核心占用的百分比不同,所以按平均值来算
  • %CPU(s)显示的是进程占用一个逻辑核的百分比,而不是整个cpu(8核)的百分比,有时候可能大于100,那是因为该进程启用了多线程占用了多个核心,所以有时候我们看该值得时候会超过100%,但不会超过总核数*100%
  • %MEM 进程使用的物理内存百分比

top界面的实用操作

进入top界面时,默认各进程是按照逻辑CPU的占用量来排序
(1)在top基本视图中,按键盘数字“1”可以监控每个逻辑CPU的状况
在这里插入图片描述
(2)敲击键盘‘y’来打开或者关闭运y行态进程的加亮效果</font>
(3)按u后输入用户名,则监控指定用户
(4)按k后输入用户进程PID,则结束指定进程
(5)按q退出top界面

找出线程占用cpu的情况

列出了进程id, 线程id、cpu占有率和执行的指令,同时按照cpu占有率排序。
pid: processor id 进程id
tid: thread id 线程id

ps H -eo user,pid,ppid,tid,%cpu,cmd --sort=%cpu

在这里插入图片描述

JVM之Jstack使用

jstack是jdk自带的线程堆栈分析工具,主要用于生成java虚拟机当前时刻的线程快照,定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等

jstack 进程id(pid)  # 控制台输出指定进程的信息
jstack  进程id >文件     #打印堆栈信息到文件中 
jstack -l  进程id    #除堆栈外,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况  

注意:
(1) jstack只能分析JVM虚拟机开启的进程
(2) jstack生成快照中,tid 是java中为这个线程的id,nid 是这个线程对应的操作系统本地线程id,每一个java线程都有一个对应的操作系统线程,且它们都是通过16进制表示的
在这里插入图片描述

实际运用

CPU占用过高的分析步骤

(1)利用top命令找到内存占用过高的进程id,可以通过按y键高亮显示正再运行的进程
在这里插入图片描述
(2)打印出指定进程的线程情况

ps H -eo user,pid,ppid,tid,time,%cpu,cmd|grep 进程id

在这里插入图片描述
(3)通过JVM自带的jstack工具生成进程快照,执行命令:jstack -l 进程id
在这里插入图片描述
通过jstack生成快照后,将第2步中查看到占用cpu过高的线程id,转换为16进制【可以通过Windows自带的程序员计算器】,然后到jstack快照中找到对应线程id的日志信息。
在这里插入图片描述

程序长时间运行也没有结果

程序长时间运行也没有结果可能是死锁了,分析步骤和上面相同

死锁信息(快照信息最后部分)
在这里插入图片描述

### 排查Tomcat中Java程序内存占用的原因 排查Tomcat中Java程序内存占用问题通常涉及多个方面,包括JVM配置、应用代码分析以及系统资源监控。以下是一些常见的排查方法: 1. **查看进程信息和线程情况** 使用`ps`命令可以查看特定Java进程的线程情况。例如,可以通过以下命令查看PID为916的Java进程的线程信息: ```bash ps p 916 -L -o pcpu,pmem,pid,tid,time,tname,cmd ``` 这有助于识别是否有某些线程占用了过多的CPU内存资源。 2. **使用jmap生成堆转储文件** `jmap`是一个非常有用的工具,用于生成虚拟机当前时刻的堆转储快照。通过这个快照,可以详细分析内存中的对象实例。例如,可以使用以下命令生成堆转储文件: ```bash jmap -dump:live,format=b,file=heapdump.hprof <pid> ``` 其中`<pid>`是Java进程的进程ID。生成的堆转储文件可以使用Eclipse MAT等工具进行分析,找出内存泄漏的根源。 3. **使用jstack生成线程快照** `jstack`可以帮助生成虚拟机当前时刻的线程快照,包含虚拟机中每一个线程正在执行的方法堆栈的集合。这对于定位线程出现长时间停顿的原因(如死锁、死循环、外部资源长时间等待等)非常有用。例如,可以使用以下命令生成线程快照: ```bash jstack <pid> > thread_dump.txt ``` 4. **检查JVM参数配置** 确保JVM的启动参数配置合理,特别是与内存相关的参数,如`-Xms`(初始堆大小)、`-Xmx`(最大堆大小)、`-XX:NewSize`(新生代大小)等。不合理的配置可能导致内存浪费或不足。 5. **监控GC行为** 通过启用垃圾回收日志记录,可以了解GC的行为和频率。例如,可以在JVM启动参数中添加以下内容以启用GC日志: ```bash -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/path/to/gc.log ``` 分析这些日志可以帮助识别是否存在频繁的Full GC或其他异常情况。 6. **使用性能监控工具** 利用专业的性能监控工具(如VisualVM、JProfiler等)可以实时监控Java应用的内存使用情况,并提供详细的内存分析报告。这些工具通常具有图形界面,操作简便且功能强大。 7. **代码审查和优化** 检查应用程序代码中是否存在内存泄漏的风险,如未关闭的流、缓存未释放的对象等。此外,还可以优化数据结构和算法,减少不必要的内存消耗。 通过以上方法,可以有效地排查Tomcat中Java程序内存占用的问题,并采取相应的措施进行优化和修复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值