Цикл утечки памяти cfmodule внутри cffunction - PullRequest
8 голосов
/ 07 января 2011

Googlers, если у вас есть дамп кучи с корнем coldfusion.runtime.CFDummyComponent, читайте дальше.

Обновление 2/22/2011

Марк Эшер из MXUnit слава нашелточно такая же ошибка в другом контексте .Его решение включает в себя большой цикл по запросу, который решается путем перехода от 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, вызвав файл oom.cfm (показан ниже).Используя 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 ( футляр от Elliott Sprehn - Adobe ColdFusion Ошибка # 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>

Ответы [ 3 ]

5 голосов
/ 07 января 2011

Я не сталкивался с этим раньше, но вот что я думаю:

Каждый раз, когда вызывается cfmodule, для него создается новое пространство памяти (которое, IIRC, является основным отличием от него и cfinclude). Поскольку вы вызываете cfmodule внутри функции, пространство памяти cfmodule технически принадлежит пространству памяти этой функции. Память функции защищена от сборки мусора, пока функция не будет завершена. Результат: куча заполняется, и вы получаете ошибку OOM.

Я не думаю, что называть это утечкой памяти - это правильно, так как она ведет себя правильно, и когда функция завершает работу, сборщик мусора может очистить блокировку этой памяти. Однако я вижу, как это может быть неудобно.

3 голосов
/ 08 января 2011

К сожалению, эта проблема проявляется множеством тегов.Я видел это с cflock внутри cfthread.Напишите очень длинный работающий цикл в cfthread, который использует cflock, в конце концов вам не хватит памяти.Это занимает много времени, но это случается.Могу поспорить, что проблема хранения существует и в обычных запросах, но у вас обычно нет цикла, который запускается сотни тысяч раз с cflock внутри, поэтому никто не замечает.

Я сообщал об этой ошибке давным-давно, но это так и не было исправлено: http://www.elliottsprehn.com/cfbugs/bugs/83359

На данный момент лучшее решение - не использовать cfmodule внутри цикла, подобного этому.Пользовательские теги действительно не были предназначены для вызова 20 000 раз за один запрос.Вместо этого вы захотите использовать UDF.В любом случае, cfmodule чрезвычайно дорог, и использование UDF будет заметно быстрее.

0 голосов
/ 03 августа 2012

Здесь обсуждается, возможно, связанная проблема утечки памяти в Coldfusion версии 9: 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. Для большинства людей существуют обходные пути (в зависимости от масштаба их проблемы), которые мало чем отличаются от описанных здесь.

...