记一次线上环境的内存溢出(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 集群,同时有两个 ...
随机推荐
- [教程]Delphi 中三种回调函数形式解析
Delphi 支持三种形式的回调函数 全局函数这种方式几乎是所有的语言都支持的,类的静态函数也可以归为此类,它保存的只是一个函数的代码起始地址指针( Pointer ).在 Delphi 中声明一般为 ...
- 【Nginx】负载均衡
本文介绍的负载均衡是针对的客户端请求在多个Nginx进程之间的均衡.注意与客户端请求在多个后端服务器之间的均衡相区别. 负载均衡问题的产生 在nginx中,建立连接的时候,会设计负载均衡问题.在多个子 ...
- leetcode ----Trie/stack专题
一:Implement Trie (Prefix Tree) 题目: Implement a trie with insert, search, and startsWith methods. Not ...
- DosBox 报错 this program requires dosxnt.exe to be in your path
也就是少了dosxnt.exe文件,能够上网搜索下载,把dosxnt 拷贝到你挂截文件夹下就能够执行 Dosxnt文件下载
- WPF的WebBrowser屏蔽弹出脚本错误窗体
WPF自带的WebBrowser在訪问一些有问题的网页时常常跳出非常多提示脚本错误的窗体, 可是WPF没有自带屏蔽这些窗体的方法或属性. 所以网上找来一使用反射的方法来屏蔽弹出脚本错误窗体的方法, 非 ...
- scala wordcount kmeans
scala wordcount kmeans k-means算法的输入对象是d维向量空间的一些点,对一个d维向量的点集进行聚类. k-means聚类算法会将集合D划分成k个聚簇.
- Semantic Parsing(语义分析) Knowledge base(知识图谱) 对用户的问题进行语义理解 信息检索方法
简单说一下所谓Knowledge base(知识图谱)有两条路走,一条是对用户的问题进行语义理解,一般用Semantic Parsing(语义分析),语义分析有很多种,比如有用CCG.DCS,也有用机 ...
- CXF 中自定义SOAPHeader
Interceptor是CXF架构中一个很有特色的模式.你可以在不对核心模块进行修改的情况下,动态添加很多功能.这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Intercep ...
- mysql连接com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link
jdbc驱动:mysql-connector-java-5.1.39-bin.jar 这个有问题, 换成:mysql-connector-java-5.1.34.jar 就可以了
- HDU3394 Railway —— 点双联通分量 + 桥(割边)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3394 Railway Time Limit: 2000/1000 MS (Java/Others) ...