Google员工,如果你有一个根目录为coldfusion.runtime.CFDummyComponent
的堆转储。
Marc Esher of MXUnit fame found the exact same bug in a different context。他的解决方案涉及从query="name"
到from="1" to="#name.recordcount#" index="row"
求解的查询的大循环。另一种方法是在循环中使用<cfthread>
:
<cfloop ...>
<cfset threadName = "thread" & createUuid()>
<cfthread name="#threadName#">
<!--- do stuff --->
</cfthread>
<cfthread action="join" name="#threadName#">
</cfloop>
当遇到需要在循环内部执行的操作(例如查询和<cfmodule>
内的<cffunction>
)时,这非常有效,因此消耗的内存仅用于该迭代。
希望别人可以确认或告诉我我做错了什么。我能够通过调用文件oom.cfm(如下所示)一致地重现运行的OOM。使用jconsole我能够看到请求消耗内存并且永远不会释放它直到完成。问题似乎是在<cfmodule>
内调用<cffunction>
,如果我注释掉<cfmodule>
调用,则在请求运行时会收集垃圾。
ColdFusion版本:9,0,1,274733
JVM参数
java.home=C:/Program Files/Java/jdk1.6.0_18
java.args=-server -Xms768m -Xmx768m -Dsun.io.useCanonCaches=false -XX:MaxPermSize=512m -XX:+UseParallelGC -Xbatch -Dcoldfusion.rootDir={application.home}/ -Djava.security.policy={application.home}/servers/41ep8/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/coldfusion.policy -Djava.security.auth.policy={application.home}/servers/41ep8/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/neo_jaas.policy -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=56033
oom.cfm (这会调用下面的template.cfm - Adobe Bug #85736)
<cffunction name="fun" output="false" access="public" returntype="any" hint="">
<cfset var local = structNew()/>
<!--- comment out cfmodule and no OOM --->
<cfmodule template="template.cfm">
</cffunction>
<cfset size = 1000 * 200>
<cfloop from="1" to="#size#" index="idx">
<cfset fun()>
<cfif NOT idx mod 1000>
<cflog file="se-err" text="#idx# of #size#">
</cfif>
</cfloop>
template.cfm
<!--- I am empty! --->
更新#2 (cfthread case from Elliott Sprehn - Adobe ColdFusion Bug #83359)
<cfthread name="test">
<cfloop from="1" to="10000" index="i">
<cflog text="This is very bad.">
<cflock name="test" timeout="10">
</cflock>
</cfloop>
<!--- Sleep a very long time (10 minutes) --->
<cfset sleep(600000)>
</cfthread>
答案 0 :(得分:5)
我之前没有碰到这个,但这就是我的想法:
每次调用cfmodule时,都会为它创建一个新的内存空间(IIRC,它与cfinclude之间的主要区别)。 因为您在函数内调用cfmodule,所以cfmodule内存空间在技术上属于该函数的内存空间。 在函数完成之前,函数的内存不受垃圾回收的影响。 结果:堆填充,并且您收到OOM错误。
我不认为调用这个内存泄漏是正确的,因为它的行为正确,并且当函数完成时,垃圾收集器可以清除该内存的保留。但是,我可以看到它可能不方便。
答案 1 :(得分:3)
遗憾的是,很多标签都存在此问题。我在cfthread中看到了这个cflock。在使用cflock的cfthread中编写一个非常长的循环循环,最终会耗尽内存。这需要很长时间,但它确实发生了。我打赌常规请求中也存在保留问题,但是你通常没有一个循环,里面有一个cflock运行数十万次,所以没有人注意到。
我很久以前就报告了这个bug,但它从来没有得到修复: http://www.elliottsprehn.com/cfbugs/bugs/83359
现在最好的解决方案是不要在这样的循环中使用cfmodule。自定义标签实际上并非用于在单个请求中调用20k次。您将要使用UDF。 cfmodule无论如何都非常昂贵,并且使用UDF的速度会明显加快。
答案 2 :(得分:0)
以下是对可能相关的Coldfusion版本9 cfc内存泄漏问题的讨论:http://forums.adobe.com/thread/1034324?start=0&tstart=0
请参阅此错误报告:https://bugbase.adobe.com/index.cfm?event=bug&id=3124148
我不相信Adobe发布了针对Verion 9.01的修复程序,但据说这个问题在版本10中已得到修复。大多数人都有解决方法(取决于他们的问题范围),这与此处描述的不同。 / p>