下面通过模拟实例分析排查Java应用程序CPU和内存占用过高的过程。如果是Java面试,这2个问题在面试过程中出现的概率很高,所以我打算在这里好好总结一下。

1、Java CPU过高的问题排查

举个例子,如下:

package com.classloading;
public class Test {
static class MyThread extends Thread {
public void run() { // 死循环,消耗CPU
int i = 0;
while (true) {
i++;
}
}
}
public static void main(String args[]) throws InterruptedException {
new MyThread().start();
Thread.sleep(10000000);
}
}

使用top命令查看占用CPU过高的进程。如下图所示。

查看进程6102下线程的占用情况,如下图所示。

使用如下命令将6122转换为16进制表示,如下:

导出CPU占用高进程的线程栈。命令如下:

jstack pid >> java.txt

内容如下:  

mazhi@mazhi:~$ cat java.txt
Attaching to remote server pid, please wait...
2021-02-23 15:38:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.192-b12 mixed mode): "Attach Listener" #10 daemon prio=9 os_prio=0 tid=0x00007f4ee0001000 nid=0x1956 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
// 这是0x17ea线程,也是占用CPU最高的线程
"Thread-0" #9 prio=5 os_prio=0 tid=0x00007f4f180d6000 nid=0x17ea runnable [0x00007f4f044da000]
java.lang.Thread.State: RUNNABLE
at com.cpuhigh.Test$MyThread.run(Test.java:8) // 这里指示第8行,则正是死循环的代码开始 ...

导出的堆栈信息有线程的状态(一般要找RUNNABLE状态)和调用堆栈结合来查找问题。线程dump分析:线程dump分析主要目的是定位线程长时间停顿的原因

2、Java 内存过高的问题排查

举个例子如下:

package com.classloading;

import java.util.ArrayList;
import java.util.List; public class Test {
private static final int UNIT_MB = 1024 * 1024; public static void main(String args[]) throws InterruptedException{
List<Object> x = new ArrayList<Object>();
int i = 0;
while(i<1000){
x.add(new byte[UNIT_MB]);
i++;
}
Thread.sleep(1000000000);
}
}

通过jmap dump内存快照。如果是线上环境,注意dump之前必须先将流量切走,否则大内存dump是直接卡死服务。

命令行输入:

jmap -histo <pid> | head -20

就可以查看某个pid的java服务占用内存排名前20的类,如下图所示。

可以看到,占用内存最多的是byte字节数组,共有1008个实例。

jmap还有一个指令可以把整个内存情况转成文件形式保存下来,如下:

jmap -dump:format=b,file=filename.bin <pid>

执行命令如下图所示。

可以在JVM启动时设置,如果发生OOM,则dump出文件。命令如下:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof

如果快照文件不大,可以下载到本地,然后通过MAT分析,也可以在线分析(https://fastthread.io/);如果快照文件很大,可以在服务器上直接分析,使用的命令是:

jhat dump.hprof

jhat也是jdk内置的工具之一。主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。命令执行后如下图所示。

访问如下图所示。

其中的Show heap histogram就会显示对象占用内在的大小。如下图所示。

  

 

Java中的CPU占用高和内存占用高的问题排查的更多相关文章

  1. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  2. Java中this、static关键字的内存图解

    Java中的关键字有很多,abstract  default  goto*  null  switch  boolean  do  if  package  nchronzed  break  dou ...

  3. java中的hashcode方法作用以及内存泄漏问题

    本文装载:http://hi.baidu.com/iduany/item/6d66dfc9d5f2da1650505870 hashCode()方法的作用&使用分析 一直以来都想写篇文章来说明 ...

  4. JAVA中的堆、栈等内存分析

    在 JAVA 中,有六个不同的地方可以存储数据 1. 寄存器( register ) 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...

  5. 在Golang中获取系统的磁盘空间内存占用

    获取磁盘占用情况(Linux/Mac下有效) import ( "syscall" ) type DiskStatus struct { All uint64 `json:&quo ...

  6. Java的8种基本数据类型的内存占用字节数和取值范围

    这是8中基本类型的内存中占用字节数(取值范围是2的(字节数X8-1)次方) 1.整型 类型 存储需求 bit数 取值范围 byte 1字节 1*8 -128-127 short 2字节 2*8 -32 ...

  7. C++中虚函数继承类的内存占用大小计算

    计算一个类对象的大小时的规律: 1.空类.单一继承的空类.多重继承的空类所占空间大小为:1(字节,下同): 2.一个类中,虚函数本身.成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空 ...

  8. C#获取CPU占用率、内存占用、磁盘占用、进程信息

    代码: using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading ...

  9. 来一波Linux中查看cpu、磁盘、内存、网络的命令

    转载请注明出处. 如果想远程管理服务器就有远程管理卡,比如Dell idRAC,HP ILO,IBM IMM 查看硬件的温度/风扇转速,电脑有撸大师,服务器就有ipmitool.使用ipmitool实 ...

随机推荐

  1. Linux环境ZooKeeper安装配置及使用

    Linux环境ZooKeeper安装配置及使用 一.ZooKeeper 1.1 zookeeper作用 1.2 zookeeper角色 1.3 zookeeper功能 二.集群规划 三.安装流程 (1 ...

  2. size_t 、wchar_t和 ptrdiff_t

    size_t在C语言中就有了. 它是一种"整型"类型,里面保存的是一个整数,就像int, long那样.这种整数用来记录一个大小(size).size_t的全称应该是size ty ...

  3. 配置VS2013 + opencv 2.4.10

    其实我内心是极力反对装这么老的版本的,但是要交课堂作业~~好无奈 [注] : 如果按照本文配置不成功,可以试一下其他博客里面的配置(多试一试总能成功的) https://jingyan.baidu.c ...

  4. Codeforces Round #657 (Div. 2) A. Acacius and String(字符串)

    题目链接:https://codeforces.com/contest/1379/problem/A 题意 给出一个由 '?' 和小写字母组成的字符串,可以将 '?' 替换为小写字母,判断是否存在一种 ...

  5. Educational Codeforces Round 85 (Rated for Div. 2)

    \(Educational\ Codeforces\ Round\ 85\ (Rated\ for\ Div.2)\) \(A. Level Statistics\) 每天都可能会有人玩游戏,同时一部 ...

  6. codeforces578C. Weakness and Poorness

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  7. KVM Pass-through 上部署 MiniSMB HurricaneII

    KVM Pass-through 上部署 MiniSMB HurricaneII 免费网络测试,是一款专门用于测试无线控制器, 智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此工具 ...

  8. OpenStack Train版-4.安装placement放置服务

    安装placement放置服务 创建placement数据库 mysql -uroot CREATE DATABASE placement; GRANT ALL PRIVILEGES ON place ...

  9. cmder设置方法

    一.添加鼠标右键 Cmder.exe /REGISTER ALL 二.添加系统环境变量 我的电脑 > 右键属性 > 高级系统设置 > 环境变量 > 系统变量,在path中添加 ...

  10. 用python写的一个自动卸载python包的脚本

    import osplist=os.popen("pip list") # 执行windows cmd命令,获取所有包package列表,并获取返回结果到plist#跳过第1,2行 ...