OOM,你怕了吗?

3 篇文章 0 订阅
1 篇文章 0 订阅

大家好,今天要给大家介绍下OOM相关的知识点。

一般这种问题出现在生产环境,本地很少出现(除非你写了死循环),所以第一件要说的就是别慌,慌是没有用的,不多逼逼,开始正文

一、如何排查

1.指定启动参数,发生异常时打印dump文件

-XX:+HeapDumpOnOutOfMemoryError:表示当JVM发生OOM时,自动生成DUMP文件。

-XX:HeapDumpPath=${目录}:表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_pid[pid].hprof,默认在启动用户根目录。

项目启动一般会指定该参数,如果没有那就加上之后重启服务,复现OOM的问题,即可得到dump文件

2.下载该文件到本地

cd 到对应的目录

sz 命令下载文件到本地(可能因为该文件过大,下载缓慢,可以考虑别的方式下载,总之就是要把他下载到你本地)

3.Profiler分析该文件

idea高版本自带profiler工具,可直接打开.hprof文件

Shallow 和 Retained heap 之间的区别

通过该工具,可以看到是哪个对象过大,代码里的拿一行导致的,一般看到这里就知道问题的所在了,接下来要做的就是看看怎么解决

二、问题的本质&解决办法

4.OOM的本质

    我们知道jvm会对对象进行垃圾回收,从新生代到老年代,如果一个对象引用一直存在,则不会被回收,这种对象经过多次垃圾回收后最终会放在老年代,而jvm老年代的大小是固定的,如果一直有这种回收不掉的对象进来,就会发生OOM;另一方面jvm的堆大小是固定的,比如1G,你要强行放个2G的数据进来,那肯定是放不下,所以OOM

4.1 哪些情况会引起OOM

    1.死循环创建对象,创建对象需要在堆中分配资源,死循环创建,堆迟早会被撑爆

    2.加载进jvm的数据过大。比如一个sql查询没有加limit,而表本身有上亿条数据,一次全加载进内存中,自然要被撑爆;又比如加载外部的excel表格数据,表格中数据太多,也会撑爆内存

    3.还有一种情况就是内存泄漏了,换句话说就是循环依赖。jvm判断一个对象是否存活(即是否需要回收该对象)有两种方法:引用计数法、可达性分析。两种方法的本质也就是确定一个对象是否还存在外部引用,如果存在,则不能回收。如果你的程序里正好有两个对象互相持有引用,那他们就都不能被回收,如果这样的对象随着时间会产生的越来越多,就会出现OOM,这也就是你们可能遇到的刚开始没事,运行了几个月之后出现了OOM

4.2 如何解决OOM

首先要明确的是具体问题具体对待了

1.假如你是mysql查询没有写limit,那加上之后就万事大吉了

2.假如你就是必须要加载一个大的excel,或者就是要在内存中操作大对象,

  a)可以考虑增大jvm的大小 

  b)页面限制功能,比如导出一个大excel结果,在页面上限制该按钮的点击次数(点击后变灰)

3.如果是内存泄漏那就需要具体再去排查了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NY_Forever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值