请先前往《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规范[翻译] 》。
相关推荐
OOM全称”Out Of Memory”,即内存溢出。 内存溢出已经是软件开发历史上存在了近40年的“老大难”问题。在操作系统上运行各种软件时,软件所需申请的内存远远超出了物理内存所承受的大小,就叫内存溢出。 内存溢出...
问题原因分析:使用ScriptEngine.eval每次都会对脚本进行编译,生成一个新的类,被GroovyClassLoader加载,大量执行计算后,将导致被加载的类数量不断增加,最终OOM。 解决办法:对计算的表达式expression进行预...
基本上解决了OOM问题 如果 方便可以直接引用BitmapManager类到 项目中使用 解决blog 地址http://www.cnblogs.com/liongname/articles/2345087.html
处理bitmap内存溢出问题
java解决大批量数据导出Excel产生内存溢出的方案
内存溢出问题是参加kaggle比赛或者做大数据量实验的第一个拦路虎。 以前做的练手小项目导致新手产生一个惯性思维——读取训练集图片的时候把所有图读到内存中,然后分批训练。 其实这是有问题的,很容易导致OOM。...
android加载大量图片内存溢出的三种解决办法
OOM分析工具-MemoryAnalyzer JVM dump分析利器
Android 图片下载以及内存处理防止OOM内存溢出 源码
Java内存溢出之PermGen_OOM
java 使用 poi 解析导入大数据量(几万数据量+)时,报出OOM。这是使用POI 第二种处理方法,解决大数据量导入内存溢出问题,并提升效率
安卓图片压缩类,避免内存溢出OOM。 利用安卓自身的计算方法。
一个很好用并且使用方法很简单的图片加载插件.自动加载和自动释放内存.完美解决大批量图片加载容易内存溢出的问题.里面有官方demo.据不可靠消息.京东和天猫都使用了该插件.
全面分析安卓内存OOM内存泄露问题,分析解决方法。安卓内核内核剖析 。
使用 strace 命令来监控内存分配,找出OOM的原因 由于使用 Netty 导致的,那错误日志里可能会出现 OutOfDirectMemoryError 错误 如果直接是 DirectByteBuffer,那会报 OutOfMemoryError Direct buffer memory
今天小编就为大家分享一篇完美解决因数据库一次查询数据量过大导致的内存溢出问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
一个android小工程,里面有我自己写的一个工具类,可以轻松避免加载图片列表内存溢出,分享给需要的朋友,工程使用android 1.6SDK完成
最近在activity嵌套webview显示大量图文发现APP内存一直在涨,没法释放内存,查了很多资料,大概是webview的一个BUG,引用了activity导致内存泄漏,所以就尝试传递getApplicationContext。 1.避免在xml直接写webview...
使用setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。解决方案:改用先通过BitmapFactory.decodeStream...
很久没上传资源了,今天特意把自己收集的,自己用过的资源上传。Android 异步加载网络的图片,开始的时候显示默认的,当加载完成图片后替换掉原来的默认图片,绝对不会发生内存溢出的问题。