メモリリークループcffModule内のcfmodule
-
08-10-2019 - |
質問
あなたがのルートとヒープダンプを持っている場合、グーグル人 coldfusion.runtime.CFDummyComponent
読む。
2011年2月22日更新
Mxunitの名声のMarc Esherは、別の文脈でまったく同じバグを見つけました. 。彼のソリューションには、から解決することで解決されたクエリ上の大きなループが含まれます 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
テストケース
ooom.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 (Elliott SprehnのCfthreadケース - 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>
解決
私はこれまでこれに出くわしませんでしたが、ここに私が起こっていると思うことがあります:
cfmoduleが呼び出されるたびに、新しいメモリスペースが作成されます(IIRCは、それとcfincludeの主な違いです)。関数内のcfmoduleを呼び出しているため、Cfmoduleメモリスペースは技術的にその関数のメモリスペースに属します。関数のメモリは、機能が完了するまでガベージコレクションから保護されます。結果:ヒープが充填され、OOMエラーが発生します。
これを正しく動作しているため、これをメモリリークと呼ぶことは正しいとは思いません。関数が完了すると、ガベージコレクターはそのメモリを保持することができます。しかし、私はそれがどのように不便であるかを見ることができます。
他のヒント
この問題は、残念ながら多くのタグで現れます。 Cfthread内のcflockでこれを見てきました。 cflockを使用する非常に長い実行ループをCFThreadに書き込み、最終的にメモリが不足します。長い時間がかかりますが、起こります。定期的なリクエストにも保持の問題が存在するに違いありませんが、通常、数十万回実行するループはありません。
私はこのバグをずっと前に報告しましたが、それは修正されませんでした:http://www.elliottsprehn.com/cfbugs/bugs/83359
今のところ最良の解決策は、このようなループ内でcfmoduleを使用しないことです。カスタムタグは、単一のリクエストで20k回を呼び出すためのものではありませんでした。代わりにUDFSを使用したいと思います。とにかくCFmoduleは非常に高価であり、UDFを使用すると著しく速くなります。
これは、おそらく関連する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で修正されていると思われる。これは、ここで説明されているものとは異なり、ほとんどの人に(問題の範囲に応じて)回避策がある。