OOM分析——错误使用Servlet API导致内存溢出

标签: oom 分析 错误 | 发表时间:2013-12-30 13:46 | 作者:
出处:http://jinnianshilongnian.iteye.com

请先前往《 Spring内存溢出问题》查看问题,大体问题就是突然间内存飙升,且CPU使用率非常高。

 

问题分析

通过内存dump分析发现内存中某个key会有几百万个,而且观察这些key会发现有时候是org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER,有时候又变成org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER,每次可能不一样。

 

这个key是springmvc放到request中的属性key,而且一个key不可能放到request多次啊,因为request attributes本身通过HashMap存储,且线程不安全;造成这个问题的能想到的就是线程绑定变量泄露/并发操作request。

 

但是问题通过观察应用,没有使用ThreadLocal模式,那么唯一可能就是并发操作request属性造成的。

 

另外,通过观察日志,发现如下异常:

[com.trs.core.frame.exceptions.handlers.ExceptionHandler] [ERROR] 2013-12-24 01:03:42 : No modifications are allowed to a locked ParameterMap 
java.lang.IllegalStateException: No modifications are allowed to a locked ParameterMap
	at org.apache.catalina.util.ParameterMap.put(ParameterMap.java:166)
	at org.apache.catalina.connector.Request.getParameterMap(Request.java:1112)
	at org.apache.catalina.connector.RequestFacade.getParameterMap(RequestFacade.java:414)
	at javax.servlet.ServletRequestWrapper.getParameterMap(ServletRequestWrapper.java:166)

抛出这个异常的唯一原因就是并发操作request造成的。更加肯定了是并发使用request造成的。

 

分析源代码

public class ParamFilter implements Filter {
   
    //省略部分代码
    	
    private ParamFilterWrapper wrapper;
	
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	wrapper = new ParamFilterWrapper((HttpServletRequest) request);
        chain.doFilter(wrapper, response);
    } 
}

发现没有,wrapper竟然是实例变量。

 

我们知道Servlet规范规定Servlet、Filter默认是单实例,即线程不安全的;假设我们有两个线程P1和P2,如果以如下方式访问:

                      P1                                         P2

01                  wrapper=request1

02                                                               wrapper=request2

03                  doFilter(wrapper)

 

发现没有,P1线程使用了P2线程的request,因此就是多线程访问request了;很可能就会遇到如上问题。大家还应该知道HashMap多线程操作时可能会遇到死循环问题,具体可以参考《 疫苗:Java HashMap的死循环》。

 

对于Servlet、Filter等请务必以线程安全的方式进行操作。对于开发人员来说,建议读读Servlet规范,中文版请参考之前翻译的《 Servlet 3.1规范[翻译] 》。

 



已有 2 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [oom 分析 错误] 推荐:

OOM分析——错误使用Servlet API导致内存溢出

- - 开涛的博客
请先前往《 Spring内存溢出问题》查看问题,大体问题就是突然间内存飙升,且CPU使用率非常高. 通过内存dump分析发现内存中某个key会有几百万个,而且观察这些key会发现有时候是org.springframework.web.servlet.DispatcherServlet.LOCALE_RESOLVER,有时候又变成org.springframework.web.servlet.DispatcherServlet.THEME_RESOLVER,每次可能不一样.

Android OOM案例分析

- - 美团点评技术团队
在Android(Java)开发中,基本都会遇到 java.lang.OutOfMemoryError(本文简称OOM),这种错误解决起来相对于一般的Exception或者Error都要难一些,主要是由于错误产生的root cause不是很显而易见. 由于没有办法能够直接拿到用户的内存dump文件,如果错误发生在线上的版本,分析起来就会更加困难.

Node.js 内存溢出OOM分析

- -
Node.js 内存飙涨以及 OOM 的问题,只要业务流量稍微复杂,一般都会遇到. 如果是堆内内存,在 OOM 之前可以打一个 Heap Profiling 进行分析,如果是 OOM 之后,可以利用 llnode 对 corefile 进行分析,但如果是堆外内存飙涨呢. 这一块内存通过 Chrome Devtool 工具是分析不出来的.

Hive中跑MapReduce Job出现OOM问题分析及解决

- - CSDN博客云计算推荐文章
今天在跑一段很复杂而且涉及数据量10多年的N个表join的长SQL时,发生了OOM的异常. 由于一个map通常配置只有64MB或者128MB,则在Map阶段出现OOM的情况很少见. 所以一般发生在reduce阶段. 但是今天这个异常详细的看后,会发现既不是map阶段,也不是reduce阶段,发现不是执行过程,而是driver提交job阶段就OOM了.

一个 redis 异常访问引发 oom 的案例分析

- - mindwind
「推断的前提是以事实为依据. 这两天碰到一个线上系统的偶尔出现突然堆内存暴涨,这倒不是个什么疑难杂症, 只是过程中有些思路觉得可以借鉴参考,故总结下并写下来. 内存情况可以看看下面这张监控图. 一天偶尔出现几次,持续时间一般几分钟不等. 当这种情况出现时,我们检查错误日志,发现有下面两几种 OOM 错误.

高并发下的oom killer

- - 操作系统 - ITeye博客
最近在搞分布式批处理平台的项目,在进行压力测试的过程中出现oom killer,而且是在linux'系统日志抛出的;. 环境:VMware虚拟机(8c/16g/100g),并发线程数:16个,称此系统为A,在A系统处理的过程中需要调用B系统的服务,是通过http协议进行的调用;. 下面描述一下排查错误的过程及相关的知识,其中一些文章是转载的一下比较好的文章;.

Android 内存溢出解决方案(OOM)

- - CSDN博客移动开发推荐文章
众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视平台而定). 因此在开发应用时需要特别关注自身的内存使用量,而一般最耗内存量的资源,一般是图片、音频文件、视频文件等多媒体资源;由于Android系统对音频、视频等资源做了边解析便播放的处理,使用时并不会把整个文件加载到内存中,一般不会出现内存溢出(以下简称OOM)的错误,因此它们的内存消耗问题暂不在本文的讨论范围.

Linux的OOM killer简单测试

- - Linux - 操作系统 - ITeye博客
       顾名思义,OOM(out of memory) killer,是Linux操作系统发现内存不足时,它会强制杀死一些用户进程(非内核进程),来保证系统有足够的物理内存进行分配.     Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序. 因为申请内存后,并不会马上使用内存.

[技术讨论]京东产品业务逻辑错误分析

- - CSDN博客推荐文章
双十一,很多人都剁了手,而作为一个程序员,更多的是看到了业务逻辑层的问题,当然,有些问题是为了让用户愿意进入,而不一定是必须花钱,比如在第一次双十一的时候的红包叠加使用,就可以让我实际当时只花了几块钱买到了一张32g的闪迪的TF卡,嗯,双十一活动价格是160,转手120卖掉了. 而因为淘宝本身的物流问题和各种假货以及欺诈行为,我已经很少在淘宝上购买东西了,而更多的转向了京东,主要是因为京东的售后服务确实对于一二线城市的人来说比较便利,三线城市也覆盖了很多.

菜鸟也能解决android中的OOM问题

- - CSDN博客移动开发推荐文章
只要你记住下面几个原则,在android 中处理图片的OOM问题绝对是easy之极:. 1.超大图片要按比例压缩之后才做显示,退出当前activity 必须回收. 关于inSampleSize 可根据自己的实际情况去定. 2.大图片(30~50k)的可直接显示,退出当前activity 立即回收. 3.大量的小图 或者不同size的图片要展示,请参看我的另外一篇LRU算法缓存图片的:http://blog.csdn.net/androidzhaoxiaogang/article/details/8211649.