Perdita di memoria Looping cfmodule all'interno cffunction
-
08-10-2019 - |
Domanda
Googler se hai un heap dump con una radice di coldfusion.runtime.CFDummyComponent
leggere.
Aggiornamento 2011/02/22
Marc Esher di MXUnit fama trovato la stessa identica bug in un contesto diverso . La sua soluzione comporta un ciclo di grandi dimensioni su una query risolto passando da query="name"
a from="1" to="#name.recordcount#" index="row"
. Un altro approccio che funziona sta usando <cfthread>
all'interno del ciclo in quanto tale:
<cfloop ...>
<cfset threadName = "thread" & createUuid()>
<cfthread name="#threadName#">
<!--- do stuff --->
</cfthread>
<cfthread action="join" name="#threadName#">
</cfloop>
Questo è molto efficace quando si esegue in situazioni in cui è necessario fare le cose all'interno del ciclo, come le query e <cfmodule>
all'interno <cffunction>
in modo che la memoria consumata è solo per tale iterazione.
Vecchio Question
Nella speranza che qualcun altro può confermare o dirmi che cosa sto facendo male. Sono in grado di riprodurre in modo coerente un OOM esecuzione chiamando il file oom.cfm (vedi sotto). Utilizzando JConsole Sono in grado di vedere la memoria richiesta consuma e non lo rilascia fino a completa. Il problema sembra essere chiamando <cfmodule>
all'interno di <cffunction>
, dove se io commento la <cfmodule>
cose chiamata sono garbage collection, mentre la richiesta è in esecuzione.
versione ColdFusion : 9,0,1,274733
Argomenti 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
Test Case
oom.cfm (Ciò richiede template.cfm qui sotto - Adobe Bug # 85.736 )
<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! --->
Aggiornamento # 2 ( cfthread caso da Elliott Sprehn - Adobe ColdFusion Bug # 83.359 )
<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>
Soluzione
Io non ho incontrato prima, ma ecco quello che penso sta accadendo:
Ogni cfmodule volta che viene chiamato, un nuovo spazio di memoria è stato creato per esso (il che, IIRC, è la principale differenza tra questo e cfinclude). Perché si sta chiamando il cfmodule all'interno della funzione, lo spazio di memoria cfmodule appartiene tecnicamente allo spazio di memoria di quella funzione. La memoria della funzione è protetta dalla raccolta dei rifiuti fino a quando si fa la funzione. Risultato:. Riempimenti heap, e si ottiene un errore OOM
Non credo che chiama questa perdita di memoria a è corretto, in quanto si sta comportando in modo corretto, e quando le Completa di funzione, il garbage collector può cancellare la presa su quella memoria. Tuttavia, posso vedere come potrebbe essere scomodo.
Altri suggerimenti
Questo problema si manifesta con un sacco di tag purtroppo. Ho visto questo con cflock all'interno cfthread. Scrivi un ciclo molto lungo in esecuzione in un cfthread che usi cflock, si esaurisce la memoria alla fine. Ci vuole molto tempo, ma succede. Scommetto che il problema di ritenzione esiste nelle richieste regolari anche, ma di solito non hanno un ciclo che viene eseguito centinaia di migliaia di volte con un interno cflock in modo che nessuno le comunicazioni.
I segnalato questo bug molto tempo fa, ma non ha mai avuto risolto: http://www.elliottsprehn.com/cfbugs/bugs/83359
La soluzione migliore per ora è quello di non uso cfmodule all'interno di un ciclo come questo. tag personalizzati in realtà non erano destinate per chiamare 20k volte in una singola richiesta. Si sta andando a voler utilizzare UDF invece. cfmodule è estremamente costoso e comunque utilizzando un UDF sarà notevolmente più veloce.
Ecco una discussione di un possibilmente correlate versione Coldfusion 9 cfc problema di perdita di memoria: http://forums.adobe.com/thread/1034324?start=0&tstart=0
Vai a questa segnalazione di bug su di esso: https://bugbase.adobe.com /index.cfm?event=bug&id=3124148
Non credo Adobe ha rilasciato una correzione per verion 9.01, ma si suppone questo problema è stato risolto nella versione 10. Non ci sono soluzioni alternative per la maggior parte delle persone (a seconda della portata del loro problema) per questo non diversamente da ciò che è stato descritto qui.