Java 应用常见问题分析

        在研发的过程中,我们肯定都遇到过各种各样的应用问题,下面总结一些常见问题及相关解法,包括但不限于CPU飙升、线程死锁、内存泄露、垃圾回收问题、类加载问题、网络问题、日志问题和安全性问题,后续会持续补充完善

1、CPU飙升(CPU Spike)

a、可能会产生的影响
  • 响应时间延长:CPU使用率过高会导致进程无法及时处理请求,从而导致Web应用的响应时间延长,影响用户体验。
  • 性能下降:高CPU使用率会消耗系统资源,导致其他进程或服务的性能下降,可能引起整体系统的不稳定性。
  • 可用性降低:CPU使用率过高持续一段时间,可能导致Web应用崩溃或无法正常运行,从而降低系统可用性。
b、可能导致的原因
  • 大量并发请求:大量并发请求时,可能会导致CPU使用率升高,特别是在处理复杂的请求或计算密集型任务时。

  • 资源泄露:内存泄露、数据库连接未释放或文件句柄未关闭等资源泄露问题可能导致CPU使用率持续增长。

  • 代码问题:低效的算法、非优化的数据库查询、死循环、频繁的IO操作等代码问题可能导致CPU使用率升高。
c、实际操作分析原因

使用 top 命令定位最耗 CPU 的进程

Java 应用常见问题分析_第1张图片

找到该进程下最耗费cpu的线程   top -Hp pid

Java 应用常见问题分析_第2张图片

此时得到的线程ID(pid)为10进制数据,方便匹配stack中的信息,转为 16 进制,俩种转换方式

a、手动转换进制 printf “%x\n” 2608    // 转换16进制(转换后为0xa30)

b、在线工具转换  >>  在线进制转换

使用 16 进制的线程ID(xa30)匹配堆栈信息,jstack pid |grep 'threadId'  -C5 --color 

Java 应用常见问题分析_第3张图片

根据该线程的堆栈信息结合实际代码分析CPU飙升的具体原因

2、线程死锁(Thread Deadlock)

死锁:指两个或多个线程互相等待对方释放资源而无法继续执行的情况

a、可能会产生的影响
  • 应用停滞或崩溃:当线程死锁发生时,涉及的线程将无法继续执行,导致应用停滞或崩溃。这会影响应用的可用性和用户体验。
  • 资源浪费:死锁会导致线程无法释放已经占用的资源,从而导致资源的浪费。这可能会降低应用的性能,并占用系统的资源。
b、可能导致线程死锁的原因
  • 竞争资源:多个线程同时竞争有限的资源,当资源分配和释放不当时,可能会导致死锁
  • 循环等待:线程之间相互等待对方释放资源,形成循环等待的局面
c、实际操作分析原因

查看 java 进程的线程快照信息并过滤死锁信息 jstack -l 2598 | grep deadlock,线程死锁的程序,会导致某些操作处于waiting中

Java 应用常见问题分析_第4张图片

3、内存泄露(Memory Leak)

指的是在程序中动态分配的内存空间在不再使用时无法被回收,导致这部分内存无法再被其他程序使用。这种情况下,应用程序所占用的内存会不断增加,最终可能导致系统的内存耗尽,导致系统服务OOM(OutOfMemoryError)异常或崩溃

a、可能产生的原因

内存泄漏的原因通常是由于程序中存在对内存的引用,导致垃圾回收器无法回收这些被引用的内存。常见的内存泄漏原因,包括但不限于以下几点:

  • 对象引用未及时释放:当一个对象不再使用时,如果其引用没有被及时释放,垃圾回收器无法回收该对象,从而导致内存泄漏。如 ThreadLocal 未执行 remove
  • 静态集合对象未清理:静态集合对象在整个应用生命周期中保持引用,如果不及时清理其中的对象引用,会导致内存泄漏。
  • 资源未正确关闭:当使用一些需要手动关闭的资源(如文件、数据库连接、网络连接等)时,如果在使用完毕后未正确关闭或释放资源,会导致内存泄漏。
  • 缓存未正确管理:在缓存中存储的对象如果长时间不被使用,却一直保持在缓存中,会导致内存泄漏。
  • 循环引用:当多个对象之间形成循环引用关系时,即使这些对象没有被外部引用,它们也无法被垃圾回收器回收,从而导致内存泄漏。
b、实际操作分析原因

jmap -heap pid  首先排查新生代、老生代堆的内存分配情况,是否分配合理或过小 

Java 应用常见问题分析_第5张图片

排查 gc   fgc ,各分代内存情况,每秒输出一次 gc 分代内存分配情况,以及gc时间

Java 应用常见问题分析_第6张图片

如果 GC 没问题,查看进程占用内存比较大的对象并分析,对于占用空间很大的对象(比如超过了100M),应该着重分析,为何没有释放。

对于堆外内存还需要考虑类的加载情况,jmap -histo:live 2598 | more  执行后会执行执行一次fgc,生产环境不建议使用,可采用dump内存快照,通过线下工具(jprofilter、MAT等)分析

Java 应用常见问题分析_第7张图片

dump内存快照的命令

jmap -dump:format=b,file=./dump.dat pid: 把Java heap里所有对象都dump下来,无论对象是死是活

 jmap -dump:format=b,live,file=xxx.hprof :先做一次full GC,然后再dump;垃圾对象会被GC清理掉,不会出现在dump文件中

持续补充完善中......

你可能感兴趣的:(实战问题汇总,java,jvm,问题分析排查)