定位排查Java线上内存溢出问题(服务重启,没有捕获到日志)

一、场景

        线上项目device服务模块内存不断上涨导致CPU较高,导致触发脚本执行重启,接口自动化测试平台不断的报500拒绝连接等错误提示。

排查:

        通过服务器日志查询并没有异常错误信息打印,查看docker容器的日志发现错误是打印控制台,无法从控制台中找到有价值的日志

短暂方案解决:

        内存溢出问题因为JVM内存分配不够大导致的,调大JVM的内存可以短暂解决此问题,但解决不了根本问题,需要从代码层去定位排查

二、Java启动参数分析(调试参数)

调试参数列表:

参数及其默认值

-XX:-CITime

打印消耗在JIT编译的时间

-XX:ErrorFile=./hs_err_pid<pid>.log

保存错误日志或者数据到文件中

-XX:-ExtendedDTraceProbes

开启solaris特有的dtrace探针

-XX:HeapDumpPath=./java_pid<pid>.hprof

指定导出堆信息时的路径或文件名

-XX:-HeapDumpOnOutOfMemoryError

当首次遭遇OOM时导出此时堆中相关信息

-XX:OnError="<cmd args>;<cmd args>"

出现致命ERROR之后运行自定义命令

-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"

当首次遭遇OOM时执行自定义命令

-XX:-PrintClassHistogram

遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同

-XX:-PrintConcurrentLocks

遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同

-XX:-PrintCommandLineFlags

打印在命令行中出现过的标记

-XX:-PrintCompilation

当一个方法被编译时打印相关信息

-XX:-PrintGC

每次GC时打印相关信息

-XX:-PrintGC Details

每次GC时打印详细信息

-XX:-PrintGCTimeStamps

打印每次GC的时间戳

-XX:-TraceClassLoading

跟踪类的加载信息

-XX:-TraceClassLoadingPreorder

跟踪被引用到的所有类的加载信息

-XX:-TraceClassResolution

跟踪常量池

-XX:-TraceClassUnloading

跟踪类的卸载信息

-XX:-TraceLoaderConstraints

跟踪类加载器约束的相关信息

 

三、项目配置启动参数

1、打开docker-compose.yaml,进行编辑

 

1、表示JVM启动运行内存的配置

2、表示当前配置首次遭遇OOM时导出此时堆中相关信息

3、表示运行的jar

4、表示运行所指向的配置

只要发生OOM,就会将对应的堆文件导出,可以根据堆文件进行问题排查

四、MAT工具使用

        是一个快速且功能丰富的Java堆分析器,可以定位排查内存泄漏的问题

1、安装独立版本的MAT

        下载压缩包解压到本地文件夹中,解压完就可以直接使用,双击运行

        下载地址:http://www.eclipse.org/mat/downloads.php

 

2、从生产环境将导出的dump内存快照文件存在本地

3、导入dump的文件

 4、分析

 

 

 

 

Shallow Heap浅堆:java对象占用的内存

Retained Heap深堆:java对象及对象引用的类占用的内存 ,jvm gc回收时释放的内存

Retained Heap深堆大于等于Shallow Heap浅堆

5、定位代码抛出抛出异常分析

 

从这个报错线程里面我们可以发现关键的几个类或者几个方法:

com.seirobotics.device.service.task.ThreadExportCsvData.exportCsvData()V (ThreadExportCsvData.java:74)

com.seirobotics.device.service.impl.DeviceFromMongoServiceImpl.getDeviceStatusBySns(Ljava/util/List;Ljava/lang/String;)Ljava/util/List; (DeviceFromMongoServiceImpl.java:455)

org.springframework.data.mongodb.core.MongoTemplate.find(Lorg/springframework/data/mongodb/core/query/Query;Ljava/lang/Class;Ljava/lang/String;)Ljava/util/List; (MongoTemplate.java:823)

通过以上的排查,我们已经定位到代码的报错的位置,最后我们再回归代码进行检测代码,然后找到问题点进行改正。

重点:通过配置ymal文件,产生内存溢出时,会自动将堆文件给导出到服务器,通过堆文件去排查定位问题

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值