请先前往《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规范[翻译] 》。
相关推荐
3. **配置不当**:服务器或虚拟机的内存设置不合理,也可能触发内存溢出错误。 #### 影响及应对策略 内存溢出会使应用程序崩溃,严重影响用户体验和业务运行。为避免这种情况,可以: - 优化算法,减少不必要的...
OOM全称”Out Of Memory”,即内存溢出。 内存溢出已经是软件开发历史上存在了近40年的“老大难”问题。在操作系统上运行各种软件时,软件所需申请的内存远远超出了物理内存所承受的大小,就叫内存溢出。 内存溢出...
基本上解决了OOM问题 如果 方便可以直接引用BitmapManager类到 项目中使用 解决blog 地址http://www.cnblogs.com/liongname/articles/2345087.html
在生产环境中,持续监控Tomcat的内存使用情况,设置合理的JVM内存参数,并定期进行内存分析,以便尽早发现和解决问题。 通过以上步骤,我们可以利用MAT有效地诊断和解决Tomcat的内存溢出问题。理解MAT的使用方法...
问题原因分析:使用ScriptEngine.eval每次都会对脚本进行编译,生成一个新的类,被GroovyClassLoader加载,大量执行计算后,将导致被加载的类数量不断增加,最终OOM。 解决办法:对计算的表达式expression进行预...
- 使用内存分析工具(如VisualVM或YourKit Java Profiler)监控内存使用情况,找出内存泄漏或不必要的对象引用,进行优化。 通过这些方法,我们可以在处理大量数据导出到Excel时避免内存溢出问题,同时保持程序的...
// 处理内存溢出错误,可能需要重新调整inSampleSize或采用其他策略 } ``` 通过上述方法,开发者可以在保持应用性能的同时,有效地处理`Bitmap`内存溢出问题,避免应用崩溃,提升用户体验。在实际开发中,根据具体...
内存溢出(Out of Memory,OOM)通常发生在系统无法分配足够的内存给程序运行时,这可能导致服务器崩溃或性能急剧下降。 标题中的"解决jetty8内存溢出版本"意味着我们面对的是一个针对Jetty 8的特殊构建或配置,其...
在安卓(Android)开发中,内存管理是至关重要的一个环节,因为不当的内存使用可能导致应用程序崩溃或者性能下降,其中最常见的问题就是内存溢出(Out of Memory,简称OOM)。本资料包"安卓Android源码——防止内存...
- 理解Java内存模型(堆、栈、方法区等)对使用内存分析工具至关重要。 总之,HeapAnalyzer是Java开发者处理内存溢出问题的强大助手。通过熟练掌握其使用,我们可以有效地定位并解决内存问题,提升应用的稳定性和...
然而,当处理大数据量的Excel文件时,POI可能会导致内存溢出(Out of Memory, OOM),因为默认情况下它会将整个工作簿加载到内存中。为了防止这种问题,我们需要采用优化策略来高效地处理大量数据。 1. **分块读取*...
MemoryAnalyzer(MAT)是IBM开发的一款强大的JVM堆内存分析工具,它能够帮助开发者深入理解内存消耗,识别内存泄漏和不必要的对象留存,从而有效地解决OOM问题。 MAT主要基于.hprof文件进行分析,这种文件格式是...
在Android应用开发中,图片加载是一项关键任务,尤其是在处理大量图片时,如果不妥善处理,很容易导致内存溢出(OOM)问题。"图片异步加载插件"正是一款为解决这个问题而设计的工具,它能够有效地优化内存管理,提高...
- **合理使用缓存**:对于需要缓存的对象,要考虑到其生命周期,避免无限增长导致内存溢出。 ##### 6. **使用合适的垃圾回收器** 选择合适的垃圾回收器对提高应用性能同样重要。例如: - **Serial GC**:适合单核...
在Android开发中,内存管理是至关重要的,尤其是处理图片资源时,经常遇到内存溢出(Out Of Memory,简称OOM)的问题。本项目提供了一个在Android 1.6 SDK环境下编写的工具类,旨在帮助开发者有效地避免内存溢出,...
在Android开发中,图片的加载和内存管理是一个关键问题,特别是考虑到防止因内存溢出(Out Of Memory,简称OOM)而导致应用崩溃。本教程将详细探讨如何在Android中有效地进行图片下载和内存处理,以避免OOM的发生。 ...
在安卓开发中,图片处理是一项常见且重要的任务,然而,如果不妥善处理,它可能会导致一个严重的问题——内存溢出(Out Of Memory,简称OOM)。内存溢出是由于程序请求的内存超过了系统分配的最大内存,从而导致程序...
分析`heapDump.hprof`文件可以使用各种工具,例如Oracle的JVisualVM、Eclipse Memory Analyzer Tool (MAT)或IntelliJ IDEA自身的内存分析插件。这些工具可以帮助我们找出内存泄漏的根源,例如查找长时间存活且占用...