views:

673

answers:

3

I'm having issues with ColdFusion's heap. Here's a little example application I'm experimenting with. I thought after cfinvoke calling the init method it destroys all variables local to the component. But apparently it's not the case. The application works as it is below but if I add a zero to the loop in index.cfm it breaks. What's stored in the heap to cause that? Is there a way around this?

index.cfm:

<cfloop from="1" to="1000" index="i">  
    <cfinvoke component="test" method="init" returnvariable="x">  
</cfloop>  
<cfoutput><p>#x#</p></cfoutput>

test.cfc:

<cfcomponent output="false">  
    <cffunction name="init" returntype="string">  
        <cfset var test = structNew()>  
        <cfloop from="1" to="1000" index="i">  
            <cfset test[i] = i>  
        </cfloop>  
        <cfreturn Now()>  
    </cffunction>  
</cfcomponent>

And here's the error message:

 SEVERE: Servlet.service() for servlet CfmServlet threw exception  
 javax.servlet.ServletException: ROOT CAUSE:  
 java.lang.OutOfMemoryError: Java heap space`

Any help would be appreciated.

+3  A: 

This is a known problem and CURRENTLY there is no way around it. It seems that CF DOES NOT handle garbage collection properly. As far as I can tell it will not destroy and free up memory used by component until after the request has finished.

Because of that, depending on how many properties your components has will determine how many of them you can create until you get the heap error.

I know this doesn't help your problem, but at least now you can take measures to prevent it.

rip747
+1  A: 

rio747 is correct, the memory does not free until the request has ended, so you are simply running out of memory. I would venture to say you can probably run it and get the error, remove the 0 and it will run; the java garbage collection is running, but not until the request is ended.

Your only options for resolution is to not create as many objects in a single request (maybe some more information about why this is necessary?) or to increase the amount of memory available to coldfusion.

I don't think this is really a problem or CF not handling garbage collection properly; from a java standpoint as long as that request is active the object could still be used and referenced. I mean, you are right about the cfinvoke and how it works, but that doesn't mean that the jvm can actually run garbage collection on those memory locations until the request is ended.

Ryan Guill
A: 

I have just posted a new blog entry which shows how you can do programmatic garbage collection if your memory gets below a certain threshold.. Hope it helps:-

[http://www.beetrootstreet.com/blog/index.cfm/2009/6/25/Clearing-ColdFusion-memory-using-garbage-collection-when-memory-gets-low][1]

your post is correct in that force the garbage collector, however it still doesn't help the heap issue when creating many objects since they will not be flagged for garbage collection until after the request is finished.
rip747