0
点赞
收藏
分享

微信扫一扫

谈谈mysql——Binlog的复制方式和解析技巧

朱悟能_9ad4 2023-07-13 阅读 67
jvmjava

现象描述:

        用户在进行报表下载过程中,每隔几天系统就会报错500,导致无法进行报表下载。

原因分析:

通过查看系统log日志以及gc日志,发现是因为下载报表过程中JVM频繁进行Full GC,而且老年代的堆内存不断增加且无法回收,最终导致OOM。

问题排查:

  1. 审查代码,发现存在很多共用的变量位于for循环之中
  2. 出现OOM可能存在如下问题
  •  JVM堆内存设置偏小
  • 程序中存在大对象无法回收

解决方案:

  1. 将公共变量提取到for循环外面共用(可以减少对象创建,但不是导致OOM的核心)
  2.    a. 将原先内存扩大一倍(系统正常使用时长比原先多几天,但最终仍会报OOM)

b. 通过工具分析堆内存快照,定位到代码中存在大对象

排查中核心过程:

查看项目日志文件

应用日志文件:显示Java Heap OutOfMemory错误

GC日志文件:新生代/老年代内存均占满,且进行Full GC内存无变化,导致OOM

GC日志

导出堆快照Dump.hprof二进制文件

注意: 使用jdk自带的jpsjmap命令(jdk必须是完整的,不能是简化版的,jdk/bin下有jpsjmap,否则不支持相关命令)

 1.jps –l该命令显示本地所有的正在运行的服务信息,包括进程id和服务名称

2.使用该服务功能后,通过jmap -dump:file=C:/tmp/dump.hprof 4672 导出对应进程ID(4672)的堆快照文件到指定的位置(C:/tmp/)

3.使用Jprofiler工具分析堆内存快照文件

  1. 首先下载jprofiler工具到本地并安装成功
  2. 使用jprofiler打开此前生成的dump.hprof二进制文件

        3.选择其中的Biggest Objects选项栏位,并从大到小排列显示堆内存中对象

可以看到各个对象内存占比

         4. 我们会发现workbook该对象大小占比55%,显然是个超大对象,因此我们需要检查该对象在执行完成后是否释放

修改代码

  1. 根据代码审查,发现该对象使用完后并未及时释放,导致该对象一致被引用且大小不断增大导致最终不断Full GC且内存无法释放,形成OOM现象。
  2. 在原有功能代码执行完成后调用workbook.close()方法释放对象引用

将修改后的代码打包上传到私服Nexus仓库

如下截图为通过STS工具将本地项目打jar包推送到nexus仓库中的流程

注意:maven命令为cleandeploy; jre需要选择本地的jdk目录

推送成功

如果没有执行mvn install指令,后续需要重新执行此命令,更新maven引用后其他引用此包的代码才不会报找不到该包下的方法错误

重新发布并部署项目,查看GC日志,显示GC正常

查看线上项目GC情况

举报

相关推荐

0 条评论