`
jinnianshilongnian
  • 浏览: 21505172 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418798
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008948
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639576
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259964
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597401
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250249
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5859076
Group-logo
跟我学Nginx+Lua开...
浏览量:702284
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785272
社区版块
存档分类
最新评论

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

阅读更多

请先前往《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规范[翻译] 》。

 

6
0
分享到:
评论
3 楼 jiasanshou 2014-03-04  
第9行执行的参数 wrapper 有可能是其他线程执行第8行后的值。
chain.doFilter(new ParamFilterWrapper((HttpServletRequest) request), response); 
2 楼 jinnianshilongnian 2013-12-30  
ss135ss 写道
顶,非常感谢开涛兄帮忙解决问题,我们遇到的就是这个问题。 :    D

可以看看翻译的servlet规范
1 楼 ss135ss 2013-12-30  
顶,非常感谢开涛兄帮忙解决问题,我们遇到的就是这个问题。 :    D

相关推荐

    内存泄漏与内存溢出

    3. **配置不当**:服务器或虚拟机的内存设置不合理,也可能触发内存溢出错误。 #### 影响及应对策略 内存溢出会使应用程序崩溃,严重影响用户体验和业务运行。为避免这种情况,可以: - 优化算法,减少不必要的...

    MySQL OOM(内存溢出)的解决思路

    OOM全称”Out Of Memory”,即内存溢出。 内存溢出已经是软件开发历史上存在了近40年的“老大难”问题。在操作系统上运行各种软件时,软件所需申请的内存远远超出了物理内存所承受的大小,就叫内存溢出。 内存溢出...

    使用MAT分析Tomcat内存溢出

    在生产环境中,持续监控Tomcat的内存使用情况,设置合理的JVM内存参数,并定期进行内存分析,以便尽早发现和解决问题。 通过以上步骤,我们可以利用MAT有效地诊断和解决Tomcat的内存溢出问题。理解MAT的使用方法...

    android 图片内存溢出(OOM)解决

    基本上解决了OOM问题 如果 方便可以直接引用BitmapManager类到 项目中使用 解决blog 地址http://www.cnblogs.com/liongname/articles/2345087.html

    Groovy大量计算导致oom的解决办法

    问题原因分析:使用ScriptEngine.eval每次都会对脚本进行编译,生成一个新的类,被GroovyClassLoader加载,大量执行计算后,将导致被加载的类数量不断增加,最终OOM。 解决办法:对计算的表达式expression进行预...

    java解决大批量数据导出Excel产生内存溢出的方案

    - 使用内存分析工具(如VisualVM或YourKit Java Profiler)监控内存使用情况,找出内存泄漏或不必要的对象引用,进行优化。 通过这些方法,我们可以在处理大量数据导出到Excel时避免内存溢出问题,同时保持程序的...

    处理bitmap内存溢出问题

    // 处理内存溢出错误,可能需要重新调整inSampleSize或采用其他策略 } ``` 通过上述方法,开发者可以在保持应用性能的同时,有效地处理`Bitmap`内存溢出问题,避免应用崩溃,提升用户体验。在实际开发中,根据具体...

    解决jetty8内存溢出版本

    内存溢出(Out of Memory,OOM)通常发生在系统无法分配足够的内存给程序运行时,这可能导致服务器崩溃或性能急剧下降。 标题中的"解决jetty8内存溢出版本"意味着我们面对的是一个针对Jetty 8的特殊构建或配置,其...

    安卓Android源码——防止内存溢出浅析.zip

    在安卓(Android)开发中,内存管理是至关重要的一个环节,因为不当的内存使用可能导致应用程序崩溃或者性能下降,其中最常见的问题就是内存溢出(Out of Memory,简称OOM)。本资料包"安卓Android源码——防止内存...

    java 内存溢出分析工具 HeapAnalyzer

    - 理解Java内存模型(堆、栈、方法区等)对使用内存分析工具至关重要。 总之,HeapAnalyzer是Java开发者处理内存溢出问题的强大助手。通过熟练掌握其使用,我们可以有效地定位并解决内存问题,提升应用的稳定性和...

    java poi 导入大数据量Excel数据 防止内存溢出处理.zip

    然而,当处理大数据量的Excel文件时,POI可能会导致内存溢出(Out of Memory, OOM),因为默认情况下它会将整个工作簿加载到内存中。为了防止这种问题,我们需要采用优化策略来高效地处理大量数据。 1. **分块读取*...

    图片异步加载插件,完美oom解决内存溢出

    在Android应用开发中,图片加载是一项关键任务,尤其是在处理大量图片时,如果不妥善处理,很容易导致内存溢出(OOM)问题。"图片异步加载插件"正是一款为解决这个问题而设计的工具,它能够有效地优化内存管理,提高...

    OOM分析工具-MemoryAnalyzer.zip

    MemoryAnalyzer(MAT)是IBM开发的一款强大的JVM堆内存分析工具,它能够帮助开发者深入理解内存消耗,识别内存泄漏和不必要的对象留存,从而有效地解决OOM问题。 MAT主要基于.hprof文件进行分析,这种文件格式是...

    内存溢出解决

    - **合理使用缓存**:对于需要缓存的对象,要考虑到其生命周期,避免无限增长导致内存溢出。 ##### 6. **使用合适的垃圾回收器** 选择合适的垃圾回收器对提高应用性能同样重要。例如: - **Serial GC**:适合单核...

    android 轻松避免内存溢出

    在Android开发中,内存管理是至关重要的,尤其是处理图片资源时,经常遇到内存溢出(Out Of Memory,简称OOM)的问题。本项目提供了一个在Android 1.6 SDK环境下编写的工具类,旨在帮助开发者有效地避免内存溢出,...

    Android 图片下载以及内存处理防止OOM内存溢出 源码

    在Android开发中,图片的加载和内存管理是一个关键问题,特别是考虑到防止因内存溢出(Out Of Memory,简称OOM)而导致应用崩溃。本教程将详细探讨如何在Android中有效地进行图片下载和内存处理,以避免OOM的发生。 ...

    安卓图片压缩类,避免内存溢出OOM

    在安卓开发中,图片处理是一项常见且重要的任务,然而,如果不妥善处理,它可能会导致一个严重的问题——内存溢出(Out Of Memory,简称OOM)。内存溢出是由于程序请求的内存超过了系统分配的最大内存,从而导致程序...

    idea git提交内存溢出后dump文件

    分析`heapDump.hprof`文件可以使用各种工具,例如Oracle的JVisualVM、Eclipse Memory Analyzer Tool (MAT)或IntelliJ IDEA自身的内存分析插件。这些工具可以帮助我们找出内存泄漏的根源,例如查找长时间存活且占用...

Global site tag (gtag.js) - Google Analytics