福哥答案2020-12-28:
答案1:
使用 top 指令,服务器中 CPU 和 内存的使用情况,-H 可以按 CPU 使用率降序,-M 内存使用率降序。排除其他进程占用过高的硬件资源,对 Java 服务造成影响。

如果发现 CPU 使用过高,可以使用 top 指令查出 JVM 中占用 CPU 过高的线程,通过 jstack 找到对应的线程代码调用,排查出问题代码。

如果发现内存使用率比较高,可以 dump 出 JVM 堆内存,然后借助 MAT 进行分析,查出大对象或者占用最多的对象来自哪里,为什么会长时间占用这么多;如果 dump 出的堆内存文件正常,此时可以考虑堆外内存被大量使用导致出现问题,需要借助操作系统指令 pmap 查出进程的内存分配情况、gdb dump 出具体内存信息、perf 查看本地函数调用等。

如果 CPU 和 内存使用率都很正常,那就需要进一步开启 GC 日志,分析用户线程暂停的时间、各部分内存区域 GC 次数和时间等指标,可以借助 jstat 或可视化工具 GCeasy 等,如果问题出在 GC 上面的话,考虑是否是内存不够、根据垃圾对象的特点进行参数调优、使用更适合的垃圾收集器;分析 jstack 出来的各个线程状态。如果问题实在比较隐蔽,考虑是否可以开启 jmx,使用 visualmv 等可视化工具远程监控与分析。

答案2:答案来自此链接:
首先通过top命令查看服务器负载,并定位负载较高的进程。
应用响应慢,一般有几种可能:
1.线程大量积压,导致请求响应慢
解决思路,通过jstack导出线程栈,查看等待状态的线程等待的资源,比如在等待数据库连接,那么就有可能是长事务导致连接被占用、sql查询耗时过长或者连接池大小设置不合理。
2.jvm内存分配不合理,导致GC频繁
通过开启开启gc日志,查看gc频率,如果老年代空间增长过快,full gc频率过高,可能是由于新生代空间不够,对象过早晋升造成的,考虑增大jvm内存。
3.jvm GC参数设置不合理,导致GC频繁
通过gc日志看到,minor gc频繁,但是老年代空间仍然快速增长,并且每次full gc后,老年代存活对象较少,在保证足够jvm内存空间的前提下,可以适当增大新生代比例,并且调整survirorRatio参数。
4.内存泄漏,导致GC频繁,并且老年代回收效率低下
通过gc日志看到,老年代空间回收效率低下,考虑可能存在内存泄漏或者大对象未及时释放的情况,可以通过jmap导出dump文件,并通过MAT工具分析是否存在内存泄漏。


评论