JVM——堆内存调优(Jprofiler使用)Jprofile下载和安装很容易,故没有记录,如有需要,在评论区留言)

堆内存调优

当遇到OOM时,可以进行调参

1、尝试扩大堆内存看结果

2、分析内存,看哪个地方出现了问题(专业工具)

调整初始分配内存为1024M,调整最大分配内存为1024M,打印GC细节(如何添加JVM操作往下看)

-Xms1024m -Xmx1024m -XX:+PrintFGCDetails

在一个项目中,突然出现了OOM故障,那么该如何排除,研究为什么出错

  • 能够看到代码第几行出错:内存快照分析工具,MAT,Jprofiler
  • Dubug,一行行分析代码

MAT,Jprofiler作用:

  • 分析Dump内存文件,快速定位内存泄露;
  • 获得堆中的数据
  • 获得大的对象
  • ...

下面是一个使用Jprofile查OOM来源的示例

(已经下载好了Jprofile以及Idea插件)

首先写一个必定会OOM的代码:

java 复制代码
import java.util.ArrayList;


public class Demo {

    byte[] array = new byte[1*1024*1024];//1m

    public static void main(String[] args) {

        ArrayList<Demo> list = new ArrayList<>();
        int count = 0;

        try{
            while(true){
                list.add(new Demo());
                count = count + 1;
            }
        }catch (Exception e){

        }

    }
}

该问题会虽然用try-catch尝试捕获异常,但问题是,OOM是Error,而非Exception,因此无法排查错误。

首先:

我们需要添加一些JVM的操作,以至于我们可以在程序运行后在终端查询到JVM的反馈

1、添加JVM操作

2、添加JVM操作栏(该IDE版本为2023版,因此许多UI做出了修改,与狂神说的UI不同)

3、在VM option内写下: -Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError意思为:限制初始化堆内存大小为1M,最大堆内存为8M,Dump出OOM

接下来运行程序,终端会给出JVM信息,下列信息中,第一行表示出现OOM,位置在HeapSpace,即堆空间。第二行表示已经将堆dump出一个.hprof文件,名字为java_pid44260,你可以在文件夹中找到它,也可以直接在project中找到它

可以发现,除了java_pin44260.hprof文件外,还dump出了一个文件夹,这个文件夹中包含了大量信息,十分占用空间,如果排查完错误,记得删除。

点开java_pin44260.hprof,如果安装好Jprofile,则会直接跳转到Jprofile,这里可以看到各类占用的空间大小

跳到Biggest Objects,可以看到,大部分的内存都是由ArrayList构成的,且可以看到它的类型为byte[],现在我们里真相很近了!

点击Thread Dump,查看线程Dump,因为示例中并没有开多线程,因此问题大概率是出现在main线程中,天使线程大概率是不会出现问题的,所以直接查main,我们可以发现,main线程中发现了OOM,且给出了具体位置具体行数,

点进去,即可直接跳转到相应位置,我们发现,它直接跳到Demo.java中,光标停留在main方法上,说明问题在此,并且Jprofile给出了具体行数,17行,因此我们就可以锁定问题所在了,就在这!

java 复制代码
import java.util.ArrayList;


// Dump文件
public class Demo {

    // -Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
    byte[] array = new byte[1*1024*1024];//1m

    public static void main(String[] args) {

        ArrayList<Demo> list = new ArrayList<>();
        int count = 0;

        try{
            while(true){
//------------------------------------------------------------------
                list.add(new Demo());//问题所在!!!!!!!!!!!
//------------------------------------------------------------------
                count = count + 1;
            }
        }catch (Exception e){

        }

    }
}
相关推荐
codervibe几秒前
无微信依赖!纯网页扫码登录实现方案详解
java·后端
间彧16 分钟前
RedisTemplate介绍与使用
java·redis
icecreamstorm17 分钟前
JDBC数据库连接池
java·mysql
毕设源码柳学姐17 分钟前
计算机毕业设计Java医学生在线学习平台系统 基于 Java 的医学生在线学习平台设计与开发 Java 医学在线教育学习系统的设计与实现
java·学习·课程设计
程序无bug18 分钟前
5年Java开发经验,面试挂在MySQL InnoDB上!大厂究竟多看重MySQL?
java·后端
lixn20 分钟前
Java集合中不同的toArray方法该怎么选择
java·jvm
康闯20 分钟前
Docker 部署emberstack/sftp 镜像
java·docker·容器
Java中文社群26 分钟前
面试官:如何实现企业级MCP分布式部署?
java·后端·面试
小地瓜重新去华容道工作1 小时前
【QT】实现应用程序启动画面
java·数据库·qt
Joker—H1 小时前
【Java】JUC并发(线程的方法、多线程的同步并发)
java·开发语言·经验分享·idea