zoukankan      html  css  js  c++  java
  • Java生产环境调优—模拟一次内存溢出

      当我们在工作中,遇到线上问题:内存溢出,如何解决呢?除了物理扩大内存以外,还可以从软件角度去定位问题之所在。

      补充一下基础知识(这里以jdk8为例)

      Java的内存模型,也可以称之为:运行时数据区(规范)

      运行时数据区分为:堆、程序计数器、方法区、虚拟机栈、本地方法栈。

      Java内存结构(实现)分为:堆区和非堆区。堆区分为Young区和Old区。非堆区即Metaspace,可分为CCS(压缩类空间)和CodeCache(native code存放的内存空间),当然这两块空间不一定存在,要看是否添加了相应的配置。Young区又分为Eden区和Surviver区,对象分配初期都在Eden区上,随着年龄的增加,进入Survivor区和Old区。Surviver区又分为S0和S1两块。S0和S1两块区域是等大的,不同时使用。对象在这两块区域上不断交换,每换一次岁数加一。Eden区和Survivor区的大小比例默认为8:2,因为很多对象的存活时间非常短,用朝生夕死来比喻刚好恰当,所以Eden区要大一些。

      好了,我们通过代码来实机演示一下内存溢出的定位过程。

      1、环境介绍:

      springboot 2.1.3.RELEASE,添加Web依赖、IDEA开发工具、MemoryAnalyzerTool工具

      2、实现思路:这里我们通过指定内存大小,然后不断的new对象到集合中,最终实现内存溢出的效果。

      3、代码截图:

      

      3、添加一些配置参数,见截图:

    4、启动程序,通过浏览器的127.0.0.1:9090/heap来访问,这里的9090为我设置的项目启动占用端口。控制台会输出内存溢出的日志,见截图:

        

    5、因为我们配置导出的镜像文件在./目录下,所以打开项目路径,可以看到如下文件,pid为运行该boot项目的进程号:

    6、打开mat工具,导入java_pid10393.hprof文件,在Getting Started的时候选择Leak Suspects Report,点击Finish,查看mat为我们生成的分析报告。见截图:

     7、mat已经很只能的为我们分析到出现问题的类了,当然这里是因为我们以结果为导向定义的一个简单Demo,实际生产环境中可能要更为复杂,需要耐心分析。

     8、点开Details,继续查看类的个数及占用的内存大小。

     9、从以上截图我们可以得出大小为13M的User对象,及对象个数为65789。综上分析,可以定位到是在做userList.add()的时候,出现了死循环,导致的内存被撑爆。

     10、补充一点,mbp机器上,mat软件无法打开的解决方法,参照博客:https://www.jianshu.com/p/68a657ed2286

     结束语:

      勤学如春起之苗,不见其增,日有所长。

  • 相关阅读:
    topcoder srm 681 div1
    topcoder srm 683 div1
    topcoder srm 684 div1
    topcoder srm 715 div1
    topcoder srm 685 div1
    topcoder srm 687 div1
    topcoder srm 688 div1
    topcoder srm 689 div1
    topcoder srm 686 div1
    topcoder srm 690 div1 -3
  • 原文地址:https://www.cnblogs.com/cecWork/p/13061071.html
Copyright © 2011-2022 走看看