• 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的代码:

    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){
    
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    该问题会虽然用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行,因此我们就可以锁定问题所在了,就在这!

    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){
    
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

  • 相关阅读:
    Spring Cloud(十三):Spring 扩展
    学习Python低手之路【二】python基本数据类型
    IDEA一键部署SpringBoot项目到服务器
    Controller接收Postman的raw参数时,属性值全部为空
    给视频批量添加背景图,轻松简单的操作方法
    Ubuntu20.04安装0pen3d及ISPC失败解决方案
    基于遥感大数据的信息提取技术综述
    光线追踪与全域光渲染keyshot中文
    新版 Ubuntu 中 gnome-terminal 可恶的行间距问题逼我退回了 Ubuntu 20.04
    CentOS 7.6安装JDK8过程(通过官网下载压缩包方式)
  • 原文地址:https://blog.csdn.net/whale_cat/article/details/134001532