精华内容
下载资源
问答
  • 2021-12-05 22:13:26

    一:堆内存溢出模拟

    我们先来做一个堆溢出的测试

    1: 改小堆内存的设置

    -Xms20m -Xmx20m -XX:-UseGCOverheadLimit 

    2:写一段死循环的代码

    public class HeapOOMTest {
        public static void main(String[] args) {
            List<OOMObject> userList = new ArrayList<>();
    
            while (true){
                OOMObject oomObject = new OOMObject();
                oomObject.setBytes(new Byte[1]);
                userList.add(oomObject);
            }
        }
    
    }
    @Data
    public class OOMObject {
        private Byte bytes[];
    }

    运行之后,如意得到了异常:java.lang.OutOfMemoryError: Java heap space

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    	at com.lixiucai.design.oom.HeapOOMTest.main(HeapOOMTest.java:17)

    细心的小伙伴可能要问了,上面设置的-XX:-UseGCOverheadLimit 参数是干嘛的?这个是禁用GC overhead limt exceed检查,因为我们堆内存设置的特别小,运行的时候,总是会抛出java.lang.OutOfMemoryError: GC overhead limit exceeded,而不是我们期望的java.lang.OutOfMemoryError: Java heap space,所以我们把它禁用掉。

    GC overhead limt exceed检查是Hotspot VM 1.6定义的一个策略,通过统计GC时间来预测是否要OOM了,提前抛出异常,防止OOM发生。Sun 官方对此的定义是:“并行/并发回收器在GC回收时间过长时会抛出OutOfMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存。用来避免内存过小造成应用不能正常工作。“

    上面的程序很简单,我们通过代码检查,就会发现是死循环导致的,OOMObject这个对象始终无法被GC释放掉,然后从年轻代的区域,存活到老年代的区域,一直累加,突破了堆内存设定上限,然后OOM。但当代码很多的时候,我们不可能通过这种一行一行检查代码的方式来排查问题,若是有一种工具能还原OOM时,JVM的内存情况就好了,JVN提供了一个参数,使得在OOM的时候可以转储堆内存快照dump文件,然后我们可以使用JDK自带的工具Visual VM来查看分析dump文件。

    二:堆内存dump文件生成与分析

    1.JVM设置在OOM时生成dump文件

    在JVM的参数里设置如下

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\dump

    第一个参数表示在OOM的时候生成dump文件,第二个参数设置生成的dump文件的路径

    2.使用Visual VM来分析dump文件

    Visual VM,自从 JDK 6 Update 7 以后已经作为 Oracle JDK 的一部分,位于 JDK 根目录的 bin 文件夹下,无需安装,直接运行即可。我们将服务器上生成的dump文件下载到本地,然后使用本地的Visual VM载入它。

    点击 文件 --> 装入,然后选择文件类型为 堆Dump,点击打开

     点击堆转储上的线程,可以查看线程日志,然后我们点击 类 页签,显示界面如下

     列表是支 持排序的,我们按实例数或者大小做下倒序,就会发现堆内存里比较大的对象OOMObject排在最前面,然后就是我们要在代码里去找这些大对象出现的地方,排查代码的问题。

    三:堆内存溢出的解决方案

    1.代码的问题:

    排查这些大对象出现的地方,是否有死循环,是否有没有做分页,做全表查询的代码等等。

    2.堆内存确实设置的过小,改大它:

    -Xms1024m -Xmx1024m

    更多相关内容
  • 最近在进行一个模块的开发时,在测试环境中测试没问题,然后在发布到生产环境后,经常发生堆内存溢出的错误导致服务挂了,需要排查出错误的源头。 二、排查思路 加大内存参数。通过修改docker-compose.yml文件...

    一、背景

    最近在进行一个模块的开发时,在测试环境中测试没问题,然后在发布到生产环境后,经常发生堆内存溢出的错误导致服务挂了,需要排查出错误的源头。

    二、排查思路

    1. 加大堆内存参数。通过修改docker-compose.yml文件参数调大jvm的堆内存大小。并且把错误发生时的快照保存进文件,以便重现时进行分析。(本模块是基于容器化部署)
      environment:
            - JAVA_OPTIONS=-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xmx4096m
    2. 当加大堆内存后,仍然发生了堆内存溢出,此时我们就需要获取到对应的内存快照进行分析。此时我们可以在/tmp目录下获取到对应生成的文件java_pid1.hprof。
    3. 选择一款合适的jvm内存分析软件对java_pid1.hprof进行解析分析。

    三、jvm分析软件

    本次排查过程采用的软件是jvisualvm,这是一款jdk8的bin目录下自带的一个分析工具,使用这个工具我们可以用来分析hprof文件。进入bin目录后,使用jvisualvm命令即可打开该软件

    cd /usr/bin
    jvisualvm

    进入软件后,点击左上角的图标,即可装入hprof文件

    选择生成的hprof文件装入后:

    然后点击查看异常抛出的线程。

    然后就在该线程下找到了一个熟悉的方法,发现原来有个地方一次性从数据库中查询了几十万的数据返回,导致一下子就把堆内存撑爆了,然后找到类似的地方也修改了。之所以在测试环境中没问题,是因为测试环境数据量不多。至此问题排查结束,修改对应的代码就完事了。

    展开全文
  • 一、修改一下自己的程序/tomcat配置,将内存调小一点容易调试 -XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m 二、写一个死循环测试 1、 @Test public void memoryTest(){ List<ContractTmpt> ...

    目录

    一、下载eclipse查看内存溢出工具

    1、解压打开​

    二、修改一下自己的程序/tomcat配置,将内存调小一点容易调试

     一、测试

            1、写一个死循环测试

            2、内存溢出,gc回收超过限制

            3、在自己的项目中会生成一个文件​

    二、tomcat项目

            1、打开jdk工具

            2、然后在指定位置会生成一个 .hprof文件,然后用eclipse工具打开

            3、打开过程可能有点慢,然后点击查看

            4、然后就可以排查错误了,方法名和行数都有展示


    一、下载eclipse查看内存溢出工具

    https://mirrors.tuna.tsinghua.edu.cn/eclipse/mat/1.9.0/rcp/MemoryAnalyzer-1.9.0.20190605-win32.win32.x86_64.zip

    1、解压打开

    二、修改一下自己的程序/tomcat配置,将内存调小一点容易调试

    -XX:+HeapDumpOnOutOfMemoryError -Xms20m -Xmx20m

     一、测试

            1、写一个死循环测试

    @Test
    public void memoryTest(){
        List<ContractTmpt> list = new ArrayList<>();
        while (true){
            list.add(new ContractTmpt("13241243"));
        }
    }

            2、内存溢出,gc回收超过限制

            3、在自己的项目中会生成一个文件

    4、打开eclipse工具,并打开3中的文件

    二、tomcat项目

            1、打开jdk工具

                    打开项目中的C:\Program Files\Java\jdk1.8.0_131\bin\jvisualvm.exe,如果本地项目启动会有tomcat的一个进程,打开抽样器->点击内存->点击增量就可以看出某个时间哪个类比较占用内存导致内存溢出,然后点击对dump生成快照

            2、然后在指定位置会生成一个 .hprof文件,然后用eclipse工具打开

            3、打开过程可能有点慢,然后点击查看

            4、然后就可以排查错误了,方法名和行数都有展示

    展开全文
  • 项目运行过程中,我们可能会遇到Java内存溢出Out Of Memory。此时我们可以借助内存分析工具MAT(Memory Analyzer Tool),来定位是哪里出现了问题。 一、MAT(Memory Analyzer Tool) 下载地址:Eclipse Memory ...

    目录


    前言

    项目运行过程中,我们可能会遇到Java内存溢出Out Of Memory。此时我们可以借助内存分析工具MAT(Memory Analyzer Tool),来定位是哪里出现了问题。


    一、MAT(Memory Analyzer Tool

    下载地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

    注意:JDK-8建议使用11版本,否则会提示版本不兼容

    二、软件初识

    解压后目录内有个MemoryAnalyzer.ini文件,该文件里面有个-Xmx参数。该参数表示最大内存占用量,默认为1024m。
    建议修改为小于本机内存大小,大于要分析的dump文件大小
    -startup
    plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
    --launcher.library
    plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.700.v20180518-1200
    -vmargs
    ### -Xmx1024my原本默认为1024m,此处我修改为4096m
    -Xmx4096m

    三、捕获dump文件

            首先在程序中模拟出一段内存溢出的逻辑:

        @RequestMapping("/testOutOfMemory")
        @ResponseBody
        public void testOutOfMemory() throws Exception {
            String name = "Aikes";
            for (int i = 0; i < 10000000; i++) {
                name += name;
            }
            System.out.println(name);
        }

            然后启动项目,开始准备捕获dump文件。这里的捕获方式分为两种,一种是主动捕获,一种是被动捕获:

    1、主动方式

            顾名思义,当内存溢出发生后,通过指令的方式手机当前应用程序下的内存使用情况。

    1、通过(Linux) ps -ef|grep find 或者 (Dos)netstat -ano|findstr 查找java程序运行的PID

    2、使用指令收集dump:jmap -dump:format=b,file=路径/heapdump.hprof  查到的PID

    注意:主动获取dump文件必须是一出现内存异常就获取dump文件,这样获取的文件信息才比较准确。如果无法及时获取,推荐通过第二种方式获取dump文件。

    2、被动方式

            该方式是启动Java服务时,增加额外参数。当程序发生内存溢出时自动收集dump文件:

    1、-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/oom/heapdump.hprof

            配置好后,调用我们预先模拟的内存溢出接口

            稍等片刻控制台开始打印日志,提示出现内存溢出并且已经收集到dump文件到指定目录:

    四、分析dump文件

            打开下载好的mat软件,通过file-open打开抓取到的dump文件(hprof文件)

            点击切换视图,可以看到内存占用百分之八十是因为这个线程,继续点开发现是一个超大的字符串"AikesAikesAikes...."

            此时我们已经发现了内存溢出的直接原因,接下来要寻找出现这个问题的代码在哪里。再返回到最初的大饼图,点击最下面的details。然后点击See stacktrace 堆叠追踪。

            这里可以看到完整的堆栈信息,里面可以发现我们增加模拟溢出代码的那个Java文件,并且爆发内存溢出的代码行也可以对上,至此溢出分析结束。


    总结

            模拟的内存溢出针对性很强,并且我们抓取dump文件也很及时,所以在分析的时候很简单。实际使用过程中面对的陷阱很多,需要从诸多可能中排查幕后凶手。Mat工具功能还很多,目前只是粗略的使用,后续如果有新的发现会继续补充到博文中。

    展开全文
  • 一、内存组成 通常JVM的参数我们会配置 -Xms 初始内存 -Xmx 最大内存 -XX:+UseG1GC/CMS 垃圾回收器 -XX:+DisableExplicitGC 禁止显示GC -XX:MaxDirectMemorySize 设置最大内存,默认是-xmx-survivor...
  • 堆内存溢出排查

    2020-06-05 16:27:36
    面试官:怎么排查堆内存溢出呀? 点赞再看,养成习惯,微信搜索【三太子敖丙】关注这个互联网苟且偷生的工具人。 本文 GitHub github.com/JavaFamily 已收录,有一线大厂面试完整考点、资料以及我的系列文章。 ...
  • 重点问了Java线程锁:synchronized 和ReentrantLock相关的底层实现 线程池的底层实现以及常见的参数 数据结构基本都问了一遍:链表、队列等 Java内存模型:常问的JVM分代模型,以及JDK1.8后的区别,最后还问了JVM...
  • 1、查询gc情况(每1秒钟打印一次gc情况)jstat -gcutil pid 1000:1查询结果含义:S0:幸存区1占用率S1:幸存区2占用率E:Eden区占用率O:老年区占用率M:元数据区(java8,相当于java7及之前的永久代的概念)使用大小ccs:压缩后...
  • 前言:模拟实战中排查堆内存溢出(java.lang.OutOfMemoryError: Java heap space)的问题。堆内存溢出的原因:一般都是创建了大量的对象,这些对象一直被引用着,无法被GC垃圾回收掉,最终导致堆内存被占满,没有足够...
  • 一般线上遇到比较头疼的就是OOM内存溢出问题,我们都会先看错误日志,如果错误日志能够定位出哪个类对象导致内存溢出,那么我们只需要针对问题修改bug就好。但是很多时候我们单凭日志无法定位出内存溢出问题,那么...
  • 关于Java Tomcat 内存溢出排查

    千次阅读 2018-07-17 11:14:20
    网站不知道什么时候,开始内存飙升,从 Tomcat 启动后,初始内存占用4%~5% ...一、定位造成内存溢出可能存在的问题 io流操作文档没关闭流。 往一个静态集合变量里一直压栈。 连接没释放。 Java队列没消耗。 ...
  • java内存溢出 原因与排查方法 1、 内存溢出的原因是什么? 内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,导致剩余的内存不够用,造成的内存溢出。如果出现这种现象可行代码排查: 一)是否应用...
  • 1、 内存溢出的原因是什么?内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:一)是否应用中的类中和引用变量过多使用了Static修饰 如public staitc ...
  • java 内存溢出排查
  • 一、内存溢出现象 异常堆栈: top 信息: 现象描述: 服务器发布/重启后,进程占用内存 21% 3g 左右,观察进程占用内存,以一天5%左右的速度增长,一定时间过后,java 进程内存增长到接近 90%,服务器报警。...
  • 笔者有话说 纸上得来终觉浅,绝知此事要躬行。...本文,我们就主要探讨一下堆内存溢出问题。 看我下面演示一段容易造成OOM的代码: 这段代码很简单,在main方法里面,我们不断地往oomList里面添加元素,然后使用我
  • java 内存溢出排查

    千次阅读 2018-05-26 20:28:16
    1,Java内存溢出包括:内存溢出和栈内存溢出 首先说下:内存溢出和内存泄露 内存溢出:out of memory 是指程序申请内存时没有足够的空间了 内存泄露: memroy leak,是指程序申请内存后,无法释放已申请的内存...
  • 一、问题定位 直接导出了dump文件 ...二 为何发生了内存泄漏 这个问题,就得探究LIVE_SET是个啥东西? 撸了一圈源码后,有以下收获: 1、它是netty的类:io.netty.util.internal.ObjectCleaner 下面的一个
  • linux java进程内存溢出 1、ps -ef | grep java—查看进程 2、jstat -gc pid 2000 --查看进程的垃圾回收情况,每2000毫秒输出一次 3、jmap -histo pid | head -n 100 查看pid中最占内存的对象,包括创建测次数和大小
  • Java内存泄漏的排查

    千次阅读 2021-09-06 15:06:59
    1.内存溢出 一种通俗的说法。 1、内存溢出:你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数据,出现溢出。 2、内存泄漏:你用new申请了一块内存,后来很长时间都不再使用了(按理应该释放),但是...
  • 记一次Java线上内存溢出问题排查

    千次阅读 2019-05-07 23:44:45
    1、top下对当前服务器内存有个大致了解 top后 shift+M按照内存占用由大到小排序,RES是此进程实际占用内存,%MEM是占服务器总内存的...3、利用jstat查看虚拟机堆内存情况和gc情况 jstat -gc:util<vmid> [&...
  • } } } 然后配置JVM内存,目的是为了让堆内存更容易溢出 -Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError HeapDumpOnOutOfMemoryError的意思为:Dump出一个关于OOM(OutOfMemory)的hprof文件,以供JProfiler识别 运行...
  • JVM---常规堆内存溢出场景排查方法

    千次阅读 2020-09-21 17:25:53
    文章目录前言一、堆内存溢出二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文...
  • Java内存溢出排查(必看)

    千次阅读 2019-05-17 10:58:44
    因此,OOM的排查及定位是每个Java工程师都必备的技能。 所遇到的问题 在使用scala开发的一个web服务,在用户使用中,经常出现:java.lang.OutOfMemoryError: Java heap space。而且还束手无策,每次都只能重启服务...
  • Java 内存溢出排查

    2018-10-23 20:24:17
    因此,OOM 的排查及定位是每个 Java 工程师都必备的技能。 所遇到的问题 在使用 scala 开发的一个 web 服务,在用户使用中,经常出现: java.lang.OutOfMemoryError: Java heap space 。而且还束手无策,每次都只能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,326
精华内容 6,130
关键字:

java堆内存溢出排查

java 订阅