内存泄漏循环cfmodule在cffunction内 [英] Memory Leak Looping cfmodule inside cffunction

查看:172
本文介绍了内存泄漏循环cfmodule在cffunction内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google员工如果您有一个堆转储,其根目录为 coldfusion.runtime.CFDummyComponent 请继续阅读。



< h1> Update 2/22/2011

MXEnit名誉的Marc Esher在不同的上下文中发现了完全相同的错误。他的解决方案涉及通过从 query =name从=1到=#name.recordcount #index =row。另一种工作方式是在循环内使用< cfthread>

 < cfloop ...> 
< cfset threadName =thread& createUuid()>
< cfthread name =#threadName#>
<!--- do stuff --->
< / cfthread>
< cfthread action =joinname =#threadName#>
< / cfloop>

这是非常有效的,当你遇到的情况下,你需要做循环内的事情,如查询和< cfmodule> 里面< cffunction> ,以便消耗的内存仅用于该迭代。



旧问题



希望别人确认或告诉我我做错了什么。我能够通过调用oom.cfm文件(如下所示)一致地重现OOM运行。使用jconsole我能够看到请求消耗内存,从不释放它,直到完成。该问题似乎是在< cffunction> 内调用< cfmodule> ,其中如果我注释掉< 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 (this calls template.cfm below - Adob​​e Bug#85736

 < cffunction name =funoutput =falseaccess =publicreturntype =anyhint => 
< cfset var local = structNew()/>
<!--- comment out cfmodule and no OOM --->
< cfmodule template =template.cfm>
< / cffunction>

< cfset size = 1000 * 200>
< cfloop from =1to =#size#index =idx>
< cfset fun()>
< cfif NOT idx mod 1000>
< cflog file =se-errtext =#idx#of #size#>
< / cfif>
< / cfloop>

template.cfm

 <!---我空了! ---> 

更新#2 从Elliott Sprehn的cfthread案例 - Adob​​e ColdFusion Bug#83359

 < cfthread name =test> 
< cfloop from =1to =10000index =i>
< cflog text =这很糟糕。>
< cflock name =testtimeout =10>
< / cflock>
< / cfloop>
<!---睡很长时间(10分钟)--->
< cfset sleep(600000)>
< / cfthread>


解决方案

我以前没有遇到过,我认为是这样:



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



我不认为调用这个内存泄漏是正确的,因为它的行为正确,并且当函数完成时,垃圾收集器可以清除对该存储器的保持。但是,我可以看到它可能不方便。


Googlers if you've got a heap dump with a root of coldfusion.runtime.CFDummyComponent read on.

Update 2/22/2011

Marc Esher of MXUnit fame found the exact same bug in a different context. His solution involves a large loop over a query solved by going from query="name" to from="1" to="#name.recordcount#" index="row". Another approach that works is using <cfthread> inside the loop as such:

<cfloop ...>
    <cfset threadName = "thread" & createUuid()>
    <cfthread name="#threadName#">
        <!--- do stuff --->
    </cfthread>
    <cfthread action="join" name="#threadName#">
</cfloop>

This is very effective when you run into situations where you need to do things inside the loop like queries and <cfmodule> inside <cffunction> so that the memory consumed is only for that iteration.

Old Question

Hoping someone else can confirm or tell me what I'm doing wrong. I am able to consistently reproduce an OOM running by calling the file oom.cfm (shown below). Using jconsole I am able to see the request consumes memory and never releases it until complete. The issue appears to be calling <cfmodule> inside of <cffunction>, where if I comment out the <cfmodule> call things are garbage collected while the request is running.

ColdFusion version: 9,0,1,274733

JVM Arguments

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

Test Case

oom.cfm (this calls template.cfm below - 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! --->

Update #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>

解决方案

I've not run into this before, but here's what I think is going on:

Each time cfmodule is called, a new memory space is created for it (which, IIRC, is the main difference between it and cfinclude). Because you are calling the cfmodule within the function, the cfmodule memory space technically belongs to that function's memory space. The function's memory is protected from garbage collection until the function is done. Result: heap fills, and you get an OOM error.

I don't think calling this a memory leak is correct, as it is behaving correctly, and when the function completes, the garbage collector can clear the hold on that memory. However, I can see how it might be inconvenient.

这篇关于内存泄漏循环cfmodule在cffunction内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆