Memory leaks cffunction内部的内存泄漏循环cfmodule

Memory leaks cffunction内部的内存泄漏循环cfmodule,memory-leaks,coldfusion,coldfusion-9,Memory Leaks,Coldfusion,Coldfusion 9,如果您有一个根为coldfusion.runtime.CFDummyComponent的堆转储,请继续阅读 更新日期:2011年2月22日 。他的解决方案涉及一个查询上的大循环,通过从query=“name”到from=“1”到=“#name.recordcount#”index=“row”来解决。另一种有效的方法是在循环内部使用,例如: <cfloop ...> <cfset threadName = "thread" & createUuid()>

如果您有一个根为
coldfusion.runtime.CFDummyComponent
的堆转储,请继续阅读

更新日期:2011年2月22日 。他的解决方案涉及一个查询上的大循环,通过从
query=“name”
from=“1”到=“#name.recordcount#”index=“row”
来解决。另一种有效的方法是在循环内部使用
,例如:

<cfloop ...>
    <cfset threadName = "thread" & createUuid()>
    <cfthread name="#threadName#">
        <!--- do stuff --->
    </cfthread>
    <cfthread action="join" name="#threadName#">
</cfloop>
测试用例 oom.cfm(这将调用下面的template.cfm-)


模板.cfm

<!--- I am empty! --->

更新#2()


我以前从未遇到过这种情况,但我认为是这样的:

每次调用cfmodule时,都会为其创建一个新的内存空间(IIRC是它与cfinclude的主要区别)。 因为您在函数中调用cfmodule,所以cfmodule内存空间在技术上属于该函数的内存空间。 函数的内存在函数完成之前不会被垃圾回收。 结果:堆被填满,您会得到一个OOM错误


我不认为将其称为内存泄漏是正确的,因为它的行为是正确的,当函数完成时,垃圾收集器可以清除对该内存的保留。然而,我可以看出这可能会有多不方便。

不幸的是,这个问题通过大量的标签表现出来。我已经看到了cfthread中的cflock。在使用cflock的cfthread中编写一个非常长的运行循环,最终会耗尽内存。这需要很长时间,但它确实发生了。我敢打赌,在常规请求中也存在保留问题,但通常不会有循环运行数十万次,其中包含一个cflock,因此没有人会注意到

我很久以前就报告过这个错误,但它从未得到修复:


目前最好的解决方案是不要在这样的循环中使用cfmodule。定制标签并不是为了在一个请求中调用20000次。您将希望改用UDF。无论如何,cfmodule非常昂贵,使用UDF的速度会明显加快。

这里讨论了可能与Coldfusion 9版cfc内存泄漏相关的问题:

请参阅此错误报告:


我不相信Adobe发布了Verion9.01的修复程序,但据推测,这个问题在版本10中已经解决了。对于大多数人来说(取决于他们问题的范围),这与这里所描述的没有什么不同。

我遇到过多线程占用内存的情况,并在这里发布了一些这样的情况。如果这是类似的,我也不会感到惊讶。如果你只是在循环中调用cfmodule,完全忽略函数,会发生什么呢?@Adam Tuttle:好的评论,没有这样测试过。当我尝试在请求过程中进行垃圾收集时,仍然指向
内部的
。这听起来像个bug。提交一份bug报告:OK bug logged:-追踪器仍然是现存最糟糕的东西。+1因为这也是我的怀疑。然而,这是一个错误。如果没有模块调用,函数的内存分配将在请求过程中被垃圾收集。因此,在其内部添加cfmodule调用应该使其成为该函数分配内存的一部分,并在函数超出范围(例如循环迭代)时可用于垃圾收集,但这显然不会发生。你自己认真地试一下测试用例,不管函数内部是否有modue,你都会看到。cfmodule的内存空间没有附加到命名变量,直到函数调用结束,它才超出范围。糟糕的设计还是错误?就我个人而言,我认为这只是一个糟糕的设计,但可能是错误的。将此标记为答案,但总体而言我仍然很痛苦(不是回答者提醒你)。斯弗莱恩:+1我已将你的示例添加到原始问题中。同意多次调用的想法是不好的,但这也是使用8或9年历史的代码库的问题,其中有许多编写的代码希望使用cfmodule/作为自定义标记进行调用。这应该是对OP问题的评论,因为它不需要回答
<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>
<!--- I am empty! --->
<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>