JVM问题排查

这篇具有很好参考价值的文章主要介绍了JVM问题排查。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文详细说明了Java应用运行过程中几种常见的JVM相关问题,并给出了问题排查步骤。

一、堆中OOM

现象:Java线程负载过高,JVM内存几乎占满,甚至抛出java.lang.OutOfMemoryError错误。

思路:通过jmap能查看到对内存中实例,可以查看到哪些类的实例比较多,排查出OOM原因。

工具:jmap

步骤

1.查看实例信息:

jmap -histo 14660  #查看历史生成的实例
jmap -histo:live 14660  #查看当前存活的实例,执行过程中可能会触发一次full gc

2.查看堆信息:jmap -heap

JVM问题排查,JVM

3.堆内存dump下来:

(1)jmap -dump:format=b,file=eureka.hprof 14660

(2)使用jvisualvm命令工具导入该dump文件分析

JVM问题排查,JVM

二、死锁排查

现象:多个线程处于死锁状态,无法再正常执行。

背景:当两个线程互相加了对方所依赖的锁时就会进入死锁状态,例如执行以下代码会进入死锁状态:

public class Test1 {
    public static void main(String[] args) {
        Object lock = new Object();
        Object lock1 = new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {

                    }

                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock) {

                    }

                }
            }
        }).start();
    }
}

思路:通过jmap能看到所有线程的状态,但线程状态处于blocked时候就是被加锁的状态中。

工具:jmap

步骤

  1. jps 查看进程号

  2. 用jstack 查找死锁状态中线程。

JVM问题排查,JVM

"Thread-1" 线程名

tid=0x000000079582bc98 线程id

nid=0x3e03 线程对应的本地线程标识nid

java.lang.Thread.State: BLOCKED 线程状态

三、CPU飙升

现象:JVM的CPU飙升

思路:通过top查看出占用最大的java线程id,再通过命令top -Hp找到该线程下关联的进程id,找到占用cpu最高的线程id,将其转换为十六进制,在通过jstack来查看进程状态

工具:top+jstack

步骤

  1. 用top命令查找出CPU占用最大的java进程和下面的线程;

查找CPU占用最高的进程:top 查找该进程下面的线程:top -Hp <java_pid>,可以看到该进程下所有子线程,可以找到占用CPU最高的线程Id,可以用命令:printf "%x\n" <线程id> 将十进制线程id转为十六进制,便于后面jstack命令使用打印GC日志:jstat -gc <java_pid> 5000

  1. 用jstack查找出对应线程的日志信息;

通过进程id查看栈内信息:jstack <java_pid> | grep <线程id十六进制值> -A 30(-A 30表示向下打印30行)

JVM问题排查,JVM

总结:cpu飙升可能的原因大概为:

  1. 代码存在死循环,导致消耗cpu;

  2. 代码一直在创建大对象,导致频繁GC,这个时候内存占用率也会很高;

四、频繁Full GC

问题说明:系统中某服务为图方便缓存使用一个hashmap,运行过程中会不断往里面放缓存数据,但是没有考虑这个map的容量问题,结果这个缓存map越来越大,一直占用着老年代的很多空间,时间长了就会导致full gc非常频繁,这就是一种内存泄漏,对于一些老旧数据没有及时清理导致一直占用着宝贵的内存资源,时间长了除了导致full gc,还有可能导致OOM。

这种情况完全可以考虑采用一些成熟的JVM级缓存框架来解决,比如guava、ehcache等自带一些LRU数据淘汰算法的框架来作为JVM级的缓存。

工具:jstat

步骤

  1. jstat -gc 可以评估程序内存使用及GC压力整体情况

JVM问题排查,JVM

  • S0C:第一个幸存区的大小,单位KB
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小(元空间)
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间,单位s
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间,单位s
  • GCT:垃圾回收消耗总时间,单位s

优化思路:简单来说就是尽量让每次Young GC后的存活对象都留存在年轻代里,尽量别让对象进入老年代,尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

JVM参数说明:

-Xms1536M -Xmx1536M -Xmn512M -Xss256K -XX:SurvivorRatio=6  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M 
-XX:+UseParNewGC  -XX:+UseConcMarkSweepGC  -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly 

JVM问题排查,JVM

本文由博客一文多发平台 OpenWrite 发布!文章来源地址https://www.toymoban.com/news/detail-699807.html

到了这里,关于JVM问题排查的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍

    本文主要针对于综合层面上进行分析JVM优化方案总结和列举调优参数计划。主要包含: 调优之逃逸分析(栈上分配) 调优之线程局部缓存(TLAB) 调优之G1回收器 -XX:+DoEscapeAnalysis 逃逸分析(Escape Analysis) 逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定

    2024年01月25日
    浏览(47)
  • jvm堆外内存排查详解

    内存泄漏想必大家并不陌生,对于jvm的内存泄漏,有很多排查手段和方便的排查工具,例如MAL,但是对于非jvm的内存,如直接内存的使用,排查起来较为麻烦,下面介绍一下相关的排查手段 在一次内存检查的过程中,意外发现在linux的java进程内存占用,远高于jvm的内存设定最

    2024年02月08日
    浏览(27)
  • 【JVM】Java内存泄露的排查思路?

    Java内存泄露(Memory Leak)是指在Java程序中,无用的对象占用了 堆内存 ,但无法被垃圾回收器回收释放,从而导致可用内存逐渐减少,最终可能导致内存耗尽或性能下降的问题。 说明一般对于内存泄漏。都是针对 堆 的。 程序一般出现内存泄漏会有 两个状态 一是一启动导致

    2024年02月13日
    浏览(38)
  • JVM笔记 —— 出现内存溢出错误时时如何排查

    内存溢出错误分为StackOverflowError和OutOfMemoryError,前者是栈中出现溢出,后者一般是堆或方法区出现溢出,简称OOM 1. 栈溢出 StackOverflowError 栈溢出一般都是因为没有正确的结束递归导致的,无限递归导致超出栈内存(-Xss)限制时就会抛出StackOverflowError。这种情况直接根据异常

    2024年02月13日
    浏览(31)
  • 【JVM】CPU飙高排查方案与思路

    1.使用 top命令 查看占用 cpu的情况 2.通过top命令查看后,可以查看是哪一个进程占用cpu较高,上图所示的进程为:40940 3.查看进程中的线程信息 4.可以根据进程 id 找到有问题的线程,进一步定位到问题代码的源码行号 因为根据进程ID 找到的线程id显示的是16进制,所以需要将查

    2024年02月13日
    浏览(27)
  • JVM-Cpu飙升排查及解决

    https://blog.csdn.net/m0_37542440/article/details/123679011 1. 问题情况 在服务器上执行某个任务时,系统突然运行缓慢,top 发现cpu飙升,一度接近100%,最终导致服务假死。 2. 问题排查 1. 执行 “top” 命令:查看所有进程占系统cpu的排序,极大可能排第一的就是自己的java进程,pid就是进

    2024年02月15日
    浏览(27)
  • jvm内存溢出排查(使用idea自带的内存泄漏分析工具)

    想分析堆内存溢出,一定在运行jar包时就写上参数 -XX:+HeapDumpOnOutOfMemoryError ,可以看我之前关于如何运行jar包的文章。若你没有写。可以写上参数,重启你的项目,等你的项目发生下一次堆内存溢出异常,在运行的同级文件夹,将产生类似这样一个文件 java_pid74935.hprof ,若你

    2024年02月09日
    浏览(44)
  • Java线上故障排查(CPU、磁盘、内存、网络、GC)+JVM性能调优监控工具+JVM常用参数和命令

    根据服务部署和项目架构,从如下几个方面排查: (1)运用服务器:排查内存,cpu,请求数等; (2)文件图片服务器:排查内存,cpu,请求数等; (3)计时器服务器:排查内存,cpu,请求数等; (4)redis服务器:排查内存,cpu,连接数等; (5)db服务器:排查内存,cpu,连接数

    2024年02月07日
    浏览(46)
  • CPU飙升 频繁GC排查-使用jmap histro命令来查看JVM中对象的直方图

    jmap是Java Virtual Machine Tool的一部分,它允许您生成JVM堆转储文件并执行各种诊断操作。可以使用jmap histro命令来查看JVM中对象的直方图。 以下是使用jmap histro命令的语法: 参数pid是JVM进程的ID。请注意,您需要具有足够的权限才能执行此命令。 执行上述命令后,您将获得JVM堆

    2024年01月19日
    浏览(37)
  • 线上FullGC问题排查实践——手把手教你排查线上问题

    作者:京东科技 韩国凯 问题起因是我们收到了jdos的容器CPU告警,CPU使用率已经达到104% 观察该机器日志发现,此时有很多线程在执行跑批任务。正常来说,跑批任务是低CPU高内存型,所以此时考虑是FullGC引起的大量CPU占用(之前有类似情况,告知用户后重启应用后解决问题

    2024年02月02日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包