Coldfusion OutOfMemoryError (CF9/Wheels)

2019-02-28 02:35发布

问题:

I have a function which loops over a query and updates a database row for each item. After about 7000 iterations it's throwing an out of memory error - Java heap space. Is there anything obviously wrong with this code ?

<cfloop query=loc.fixItems>
    <cfset loc.count = loc.count + 1>
    <cfset var categoryName = loc.fixItems.categoryName>
    <cfinvoke component="Item" method="updateCode"
        itemId="#loc.fixItems.itemId#" code="#loc.fixItems.newCode#"/>

    <!--- Increment counter for category --->

    <cfif structKeyExists(categoryMap, categoryName)>
        <cfset var inc = structFind(categoryMap, categoryName) + 1>
        <cfset structUpdate(categoryMap, categoryName, inc)>    
    <cfelse>
        <cfset structInsert(categoryMap, categoryName, 1)>  
    </cfif>
</cfloop>

and in the update component:

<cffunction name="updateCode">
    <cfargument name="itemId" type="numeric" required="yes">
    <cfargument name="code" type="string" required="yes">

    <cfset var loc = {}>
    <cfquery name="loc.update">
        update items
        set code = <cfqueryparam value="#code#">
        where id = <cfqueryparam value="#itemId#">
    </cfquery>
</cffunction>

回答1:

Don't use cfinvoke to create your Item component every iteration of your fixItems query. Create it once before that using createObject and simply call the updateCode method each time directly on the object.



回答2:

The following can be done:

  1. Change your <cfqueryparam> to use the appropriate cf_sql type. Are code and id really strings?

  2. Don't give your <cfquery> a name. You are not keeping the result anyway. var loc doesn't help either

  3. Bump up you memory to the JVM Addtional approach Use Java 7 and G1GC

  4. Every 100 to 1000 iterations do a forced Garbage Collect

  5. Update your data in bulk. XML based table variables can do this.

  6. Make your function silent

  7. Consider ORM on this