记一次线上环境的内存溢出(java.lang.OutOfMemoryError)
事故背景
今天客户说风控项目有个别用户查询不到数据不是报错就是一直卡在那里,我就去那个接口看了下。
一看项目日志今天的都几个g了,平常也就几百兆吧,很明显出了问题。
请求接口后使用命令tail -f 实时查看日志,发现有个东西一个在刷屏,几分钟了还在刷。
把日志切割后查看还发现了堆内存溢出错误,使用命令 free -m 发现服务器4g内存几乎已经占满了。
[2018-07-12 14:06:46,259 ERROR]:[http-bio-443-exec-12] - 错误提示 :org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:978)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.OutOfMemoryError: Java heap space

就是这个loanInfos对象,于是猜想应该是如下这个方法出问题了。

再进去看doNoFindUserReq()这个方法。。。

注意理解noLoanInfosMapper.select()方法,用过通用mapper插件的应该知道这是根据实体类里的属性进行查询。
但是这里就出现了一个问题,如果record.getTrxNo()是null的话(注意红框标注的部分之前是没有的)就相当于没有条件了,就会查询全表的数据。我看了下数据库,对应的表数据大概有17万行,也就是创建了17W个NoLoanInfos对象,所以堆内存都被用光了。
而且后面还有针对这个list的for循环操作。。。
解决办法就是添加了一个判断条件。
总结一下,导致java.lang.OutOfMemoryError内存溢出的几个原因:
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
3.代码中存在死循环或循环产生过多重复的对象实体;
4.使用的第三方软件中的BUG;
5.启动参数内存值设定的过小;
更多可以参考这里:http://outofmemory.cn/c/java-outOfMemoryError
其实,我这里写的很简单,但当时没处理过这种情况也是折腾了半天,还要被客户不停地催,不过好在下次就有经验了。
补充,可以通过更专业的方法来分析。
生成dump文件
首先,添加jvm参数生成dump文件和打印堆栈信息。
package cn.sp.chapter2; import java.util.ArrayList;
import java.util.List; /**
* @Author: 2YSP
* @Description: java堆内存溢出异常测试
* @Date: Created in 2018/1/15
*/
public class HeapOOM { static class OOMObject{ } /**
* VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:\file
* @param args
*/
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
while (true){
list.add(new OOMObject());
}
}
}
运行后对应文件夹生成dump文件java_pid11708.hprof,控制台也会打印信息。

这样很容易看出哪里出问题了。
除了上面加jvm参数的方式,还可以通过命令手动生成堆文件。
jcmd process_id GC.heap_dump /path/to/heap_dump.hprof
或者
jmap -dump:live,file=/path/to/heap_dump.hprof process_id
分析dump文件的工具
1.IBM Memory Analyzer
2.Eclipse Memory Analysis

很容易看出是OOMObject这个对象占据了大部分堆内存。
记一次线上环境的内存溢出(java.lang.OutOfMemoryError)的更多相关文章
- 记一次内存溢出java.lang.OutOfMemoryError: unable to create new native thread
一.问题: 春节将至,系统访问量进入高峰期.随之系统出现了异常:java.lang.OutOfMemoryError: unable to create new native thread.在解决这个 ...
- Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)
Tomcat启动时报如下错误: java.lang.OutOfMemoryError: PermGen space 解决办法: 配置相关内存大小.其中按照启动tomcat的不同方式,分 ...
- Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的解决办法
Tomcat启动时报如下错误: java.lang.OutOfMemoryError: PermGen space 解决办法: 配置相关内存大小.其中按照启动tomcat的不同方式,分如下三种情况 a ...
- android内存溢出 java.lang.OutOfMemoryError
今天在做ListView 的时候.想做一个音乐列表模块,前面是图片,后面是分类名称,如下图: 结果运行时候,LogCat是总是报 java.lang.OutOfMemoryError的错误,顾名思义, ...
- Java内存溢出java.lang.OutOfMemoryError: PermGen space
今天把以前的一个项目部署在tomcat,启动没问题.因为用到了webservice,当调用webservice中的方法时一直报内存溢出异常 Exception in thread "http ...
- tomcat7 内存溢出 java.lang.OutOfMemoryError: Java heap space
在{tomcat7_home}bin/catalina.sh最上面添加: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=128M -XX ...
- tomcat7 内存溢出 java.lang.OutOfMemoryError 处理方法
找到tomcat的安装目录,在 tomcat安装目录/bin/catalina.sh最上面添加: JAVA_OPTS="-server -Xms800m -Xmx800m -XX:Perm ...
- 解决eclipse maven install 造成JVM 内存溢出(java.lang.OutOfMemoryError: Java heap space)
maven install 报错信息: The system is out of resources.Consult the following stack trace for details.jav ...
- 记一次线上环境 ES 主分片为分配故障
故障前提 ElasticSearch 版本:5.2 集群节点数:5 索引主分片数:5 索引分片副本数:1 线上环境ES存储的数据量很大,当天由于存储故障,导致一时间 5个节点的 ES 集群,同时有两个 ...
随机推荐
- <项目><day12>通讯录(自己做的)
设计一个通讯录主页面 <!DOCTYPE html> <html> <head> <title>电话本首页</title> <meta ...
- 转 gSOAP中使用TCP协议传输数据
一 模型 TCP/IP是一个协议族(Internet protocol suite),包含众多的协议,传输控制协议(TCP)和网际协议(IP)分属不同的层次,是保证数据完整传输的两个基本的重要协议. ...
- 基于unicorn-engine的虚拟机的实现(WxSpectre)
反病毒虚拟机是一个很有优势的工具,可以说反病毒软件是否存在模拟器是衡量反病毒软件能力的一个指标.反病毒虚拟机不光是内嵌在反病毒软件内部,来动态执行样本.这种虚拟机一般也可以单独用来动态执行批量样本,检 ...
- 【Nginx】Hello world程序
模块如何在运行中生效 配置文件中的location块决定了匹配某种URL的请求将会由相应的HTTP模块处理,因此,运行时HTTP框架会在接收完毕HTTP请求的头部后,将请求的URL与配置文件中的所有l ...
- 简述HashMap和Hashtable的差别
1.HashMap继承AbstractMap类. Hashtable继承了Dictionary类. 2.HashMap同意有null的键和值. Hashtable不同意有null的键和值. ...
- [转]图解eclipse 查看原始类出现The jar file rt.jar has no source attachment
原文:http://blog.csdn.net/u011514810/article/details/53196371 ---------------------------------------- ...
- Android双列滑动表格(双表头不动)
※效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fil ...
- MongoDB 操作手冊CRUD 更新 update
改动记录 概述 MongoDB提供了update()方法用于更新记录. 这种方法接受下面參数: 一个更新条件的JSON对象用于匹配记录,一个更新操作JSON对象用于声明更新操作,和一个选项JS ...
- Linux —— 压缩文件
Linux——压缩文件 为什么需要压缩文件? 文件在传输过程中,可能由于文件过大,传输所需时间过多.减少文件大小有两个明显的好处,一是可以减 少存储空间,二是通过网络传输文件时,可以减少传 ...
- android锁屏软件制作
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mingyue_1128/article/details/33726515 转载请标明出处http:/ ...