I have a particular thread that I kick off when by CF9 application starts. It manages a queue and takes items from the queue to process them. If there are no items to take from the queue it will sleep()
. This thread could live for weeks, processing and sleeping etc.
The problem I am having is that the items I am taking from the queue are being retained in the heap (looks like in the Old Generation) long after I am done with them.
A full garbage collection is done by the JVM about every hour (I can tell this from jConsole), and even when that runs the items I have processed are still retained in the heap. I can tell this because I do a jmap
heap dump and analyse it using the Memory Analysis Tool Eclipse plugin.
So here is my code, this is executed in Application.cfc
:
<!--- Kick off a new thread and run through the queue --->
<cfthread action="run" name="myThread">
<cfloop condition="APPLICATION.threadProcessing eq true">
<cfif APPLICATION.myQueue.hasNext()>
<!--- Get next item --->
<cfset tmpItem = APPLICATION.myQueue.next() />
<!--- Ask item to process itself --->
<cfset tmpItem.process() />
<!--- PROBLEM: these 'tmpItem' objects are never cleaned up by the garbage collector! --->
<!--- Then we sleep for an interval - this is to stop us hogging server resources --->
<cfset sleep(2000) />
<cfelse>
<!--- Nothing in the queue, so sleep for a while... --->
<cfset sleep(10000) />
</cfif>
</cfloop>
</cfthread>
Can anyone tell me if I am using the incorrect scope or something? Is there a way to force cleanup of my temporary objects? I presumed that calling an explicit garbage collection would not work as it's not being cleaned up anyway.
This only appeared to become a problem when we moved from CF8 to CF9.
Any and all help appreciated - I really would like to keep this thread approach and not run it as a scheduled task or something.
Thanks, Ciaran.