首页 > 系统相关 >OutOfMemoryError: Java heap space/GC overhead limit exceeded 内存溢出问题排查

OutOfMemoryError: Java heap space/GC overhead limit exceeded 内存溢出问题排查

时间:2023-07-03 11:35:02浏览次数:48  
标签:java space -- jar limit 内存 JVM Java 溢出

一、背景

我开发的给产线使用的工具时不时就无法登录,查看日志基本上都是内存溢出,查看实际内存基本上都占满了JVM设置的内存大小

导致的现象就是SpringBoot项目无法登录,导致系统不可用。

下面是我的java启动设置。

javaw -Xmx6G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/java_heapdump.hprof -jar D:/CODE/FEBS-Shiro-2.0.jar --server.port=8080 --spring.profiles.active=prod 

二、排查经过

内存泄漏问题通过百度可知,需要使用jmap之类的工具将内存状态导出,然后使用eclipseMat工具进行分析。

工具使用参考Eclipse MAT内存分析工具(Memory Analyzer Tool)_eclipsemat_zhousenshan的博客-CSDN博客

通过下面的方式启动jar包,可以在内存溢出的时候将JVM内存状态保存到文件中。

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/java_heapdump.hprof

  

事后通过eclipseMat工具打开java_heapdump.hprof文件进行分析。

由于内存溢出时,我的生产环境设置的JVM是6G,所以排查问题的事后eclipseMAT也需要将JVM设置成6G

首次运行eclipseMAT的时候提示需要使用java17,下面是eclipseMAT的配置文件设置

 

-startup
plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar
-vm
D:\Java\jdk-17.0.7\bin\javaw.exe  //需要到oracle官网下载jdk17的zip版,然后解压到本地,这样不会影响我使用JDK1.8
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.700.v20221108-1024
-vmargs
--add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
-Xmx6G//这里设置成自己的内存溢出文件java_heapdump.hprof的大侠,我的文件大小差不多5G所以我设置成6G

  

打开文件后发现有一个类型的对象占用大量的堆栈

 

通过查询分析项目代码

发现有一个查询表记录并返回LIST的代码有内存泄漏的风险,修改之前,假如DMC为空,就会查询表里的所有数据,该表有800万的记录,大概查询到160万左右的时候6G的JVM内存就爆了。

增加限制代码,假如没有输入查询条件,则指定一个固定值。

 同时横向排查同类型的代码,彻底解决内存泄漏的问题。

 

标签:java,space,--,jar,limit,内存,JVM,Java,溢出
From: https://www.cnblogs.com/CryOnMyShoulder/p/17522321.html

相关文章

  • 在JAVA中使用mongoTemplate构造查询条件
    //创建条件对象Criteriacriteria=newCriteria();//3.单个条件查询多个字段(客户编号)if(StringUtils.isNotEmpty(bo.getAdmpId())){criteria.orOperator(Criteria.where("final_uid").is(bo.getAdmpId()),Criteria.where("customer_......
  • JavaScript 事件的委派
    <!DOCTYPEhtml><html> <head> <metacharset="utf-8"/> <title></title> <scripttype="text/javascript"> window.onload=function(){ varu1=document.getElementById("......
  • java中多线程synchronized锁升级的原理是什么?
    在Java中,synchronized关键字用于实现线程之间的同步,确保多个线程对共享资源的访问是有序的。当一个线程获取到对象的锁时,其他线程将被阻塞,直到该线程释放锁。Java中的锁升级是指JVM对synchronized锁的优化过程。为了提高程序的性能,JVM使用了不同的锁状态。具体的锁状态如下:无锁状态......
  • java对象的内存布局
    写java时不管是我们自己new对象还是spring管理bean,尽管我们天天跟对象打交道,那么对象的结构和内存布局有多少人知道呢,这篇文章可带你入门,了解java对象内存布局。本文涉及到JVM指针压缩的知识点,不熟悉的小伙伴可以看前面写过的一篇关于指针压缩的文章。JVM之指针压缩首先说明,本......
  • 狂收 3K Star!一个高性能、无侵入的 Java 性能监控和统计工具,十分强悍!
    背景随着所在公司的发展,应用服务的规模不断扩大,原有的垂直应用架构已无法满足产品的发展,几十个工程师在一个项目里并行开发不同的功能,开发效率不断降低。于是公司开始全面推进服务化进程,把团队内的大部分工程师主要精力全部都集中到服务化中。服务化可以让每个工程师仅在自己负......
  • java中的BO根DTO的区别以及使用场景
    java中的BO根DTO的区别以及使用场景  BO(BusinessObject)业务对象BO就是PO(PersistantObject)的组合简单的例子比如说PO是一条交易记录,BO是一个人全部的交易记录集合对象复杂点儿的例子PO1是交易记录,PO2是登录记录,PO3是商品浏览记录,PO4是添加购物车记录,PO5是搜索记录,BO是个......
  • 获取系统时间在java中怎么操作,还可以指定格式
    ​ 要在Java中获取当前时间并将其格式化为指定形式,可以使用java.time包中的LocalDateTime和DateTimeFormatter类。下面是一个示例代码,演示如何获取系统时间并将其格式化为指定的字符串格式: importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;p......
  • 获取系统时间在java中怎么操作,还可以指定格式
    ​ 要在Java中获取当前时间并将其格式化为指定形式,可以使用java.time包中的LocalDateTime和DateTimeFormatter类。下面是一个示例代码,演示如何获取系统时间并将其格式化为指定的字符串格式: importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;p......
  • 如何在JavaScript中使用Promise.allSettled()
    您是否曾经在JavaScript中使用过Promise,并且当有人拒绝并毁掉一切时感到沮丧?你编写了一些基于Promise的代码,一切都进展顺利,然后繁荣——一个小小的Promise被拒绝,整个链条就会崩溃。你的代码逐渐停止,你想知道为什么JavaScript不能忽略这个小问题并继续它的快乐之路。好......
  • Java|Spring Boot 一些名词和常用概念(1)
    JVMJVM(JavaVirtualMachine)is anabstractmachinethatenablesyourcomputertorunaJavaprogram.WhenyouruntheJavaprogram,JavacompilerfirstcompilesyourJavacodetobytecode.Then,theJVMtranslatesbytecodeintonativemachinecode(set......