环境:struts2.2.1.1 + Spring3.05 + MyBatis + Tomcat7 。
现象:Tomcat每隔一段时间就报告Out Of Memeory Exception。 分析检查得知只要在tomcat7的管理端使用stop、reload就会导致memory leak。后台报错是:The web application [/XXXX] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10]
(value [com.opensymphony.xwork2.inject.ContainerImpl$10@4a11a8]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@cd32e5]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and
avoid a probable memory leak. 网上搜索都是什么CleanUp的问题,类似于:
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ActionContextCleanUp
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
结果都不灵。struts2官网上已经不推荐使用原始的filter了,改用什么prepareddispatchfilter以后就不需要增加上面的配置了。以为是工程的问题,从官网上下载demo,googlecode,嘿嘿嘿,严重警告,涛声依旧。
过程:开始还有其余几个类似的问题,都是由于使用Threadlocal而没有及时的清理掉导致的,重构代码就解决了。但是还有些问题,包括:The web application [/XXXX] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application
was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
从网上检索类似的问题都能够解决了。比如 JDBC driver的问题,可以使用一个listener,来监听application的结束事件,在事件中unregiste所有的驱动程序。由于系统用到了Spring的timer类,还出现了10个类似于以下的问题:
The web application [/XXXX] appears to have started a thread named [scheduler_Worker-1] but has failed to stop it. This is very likely to create a memory leak.都可以在listener中进行处理掉。但是最后剩下上面的那个问题无论如何怎么修改程序都不能去掉了。看样子也是由于使用 ThreadLocal变量导致的无法清理程序造成的。使用排除法,去掉部分代码,检查问题,依旧。去掉所有编写的代码,检查问题,依旧。这里两句话,实际上用了差不多两天。最终发现是struts2使用的xwork导致的问题。参见:https://issues.apache.org/jira/browse/WW-2167,号称解决了,其实呢。。。。就是ContainerImpl,反编译ContainerImpl$10.class得到一个threadlocal的实现。嘿嘿,下载源代码吧。修改源码,在
<T> T callInContext(ContextualCallable<T> callable) {
Object[] reference = localContext.get();
if (reference[0] == null) {
reference[0] = new InternalContext(this);
try {
return callable.call((InternalContext) reference[0]);
} finally {
// Only remove the context if this call created it.
reference[0] = null;
}
} else {
// Someone else will clean up this context. ////PS:这个注释真真真。。。。。
return callable.call((InternalContext) reference[0]);
}
}
方法中,增加try finally,在最后设置localcontext为空,看看结果:直接OutOfMemory,HeapSpace。。。。看来struts源码不是随便就可以改的啊!呵呵,没关系,还有招数,增加destroy方法,手动移除threadlocal变量,并设置该threadlocal为null,结果则么样??tomcat报错了,呵呵,在checkThreadLocalMap的时候,就直接空指针了。。。怎么办,那好,既然tomcat还要求必须检查该变量,OK,我只去除threadlocal中的内容,而不动threadlocal,总可以了吧。于是使用localcontex.remove()方法,这里还有个小插曲,本意是使用while循环,去掉localcontext中的所有内容,无奈死循环。。。哦,threadlocal,每thread只有一份,嘿嘿。基础知识不牢靠,靠。打包、发布,您猜怎么着,成功了!可是虽然后台不报告错误了,在tomcat7前台,findleak的时候,依然会有报告出来,我晕。后台不报错了都,哪里有leak??发现是spring
的quartz导致的,虽然我在 listener中对其进行了处理,但是在tomcat对他进行检查的时候,这个处理还没有进行。呵呵,不管。
最终方案: 使用修改过的xwork-core.jar,我命名为xwork-core2.2.9.1.jar以示与原来2.2.1.1的区别。放到maven上,嘿嘿大家用去吧。
下载地址:
http://maven.marsorstudio.cn/org/apache/struts/xwork/xwork-core/2.2.9.1/。
下载不了告诉我,到时候再确认吧,嘿嘿,懒一下。
分享到:
相关推荐
memory leak 教程,一步一步解决内存泄漏。
This program is a tool that help you positioning memory leak locations of an QUALCOMM BREW application on simulator. It can give the call stack of memory leaks (including the locations that MALLOC/...
本文中描述了C++中常见的内存泄露,以及对应的解决方法,并且介绍了几种常见的内存泄露检查工具的使用(常见的工具只有vld和codesnitch)
一个在模拟器上定位BREW应用程序内存泄露位置的工具,可以给出内存泄露位置的调用栈信息(包括MALLOC、REALLOC分配的内存,也能定位到调用ISHELL_CreateInstance的位置)
memory leak tools for android memory leak tools for android
Memory leak detection for WinCE
内存泄漏检测器 MemoryLeakDetector是由Xigua视频android团队开发的本地内存泄漏监视工具。 它具有访问简单,监视范围广,...memory-leak-detector:0.0.7 '} 步骤3:添加代码以方便使用(使用广播控件不需要此步骤) //
检测内存泄漏的工具源码 三个文件 使用时只要include一个头文件就可以 内含一个example程序
内存泄露(memory leak)资料,网上收集的,感谢原作者
C++ memory leak detection and exception
使用__wrap_malloc查找malloc导致内存泄漏问题 memory leak 内存泄漏
This program is a tool that help you positioning memory leak locations of an QUALCOMM BREW application on simulator. It can give the call stack of memory leaks (including the locations that MALLOC/...
This document is about Memory leak.
有关flex 内存泄漏memory leak介绍的ppt. flash player的内存泄漏实在搞的我头大了
java -verbose:gc -Xloggc:gc.log -XX:+ PrintGCDetails -jar Learn-tomcat-memory-leak-0.0.1-SNAPSHOT.jar 使用jstat命令观察GC的过程 jstat -gc 94223 2000 1000 通过GCViewer工具查看GC日志 为了找到内存泄漏...
A Practical FlowSensitive and ContextSensitive C and C++ Memory Leak Detector
node-memory-leak-tutorial, 在节点中,调试内存泄漏的教程 调试 node.js 中的内存泄漏这是在 node.js. 中调试内存泄漏的快速教程步骤 1: 安装调试工具首先,你需要安装 v8-profiler 模块。 如果不需要在应用程序中...
好用的javascript内存溢出检测工具
技術分享_Glassfish 3.1.2.2 Web Service Memory Leak Workaround1
Converting a bitmap to a region - memory leak fix将位图转化为一个区域 - 修补了内存漏洞(179KB)