栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

OOM,你怕了吗?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OOM,你怕了吗?

大家好,今天要给大家介绍下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.如果是内存泄漏那就需要具体再去排查了

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/318830.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号