1

我有一个函数可以循环查询并更新每个项目的数据库行。经过大约 7000 次迭代后,它抛出了内存不足错误 - Java 堆空间。这段代码有什么明显的问题吗?

<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>

在更新组件中:

<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>
4

2 回答 2

3

不要在 fixItems 查询的每次迭代中都使用 cfinvoke 创建您的 Item 组件。在此之前使用 createObject 创建一次,每次直接在对象上调用 updateCode 方法。

于 2013-11-15T15:55:11.293 回答
1

可以执行以下操作:

  1. 更改您<cfqueryparam>以使用适当的cf_sql类型。code真的id是字符串吗?

  2. 不要给你<cfquery>的名字。无论如何,您都没有保留结果。var loc也无济于事

  3. 为 JVM 增加内存附加方法使用 Java 7 和 G1GC

  4. 每 100 到 1000 次迭代执行一次强制垃圾收集

  5. 批量更新您的数据。基于 XML 的表变量可以做到这一点。

  6. 使您的功能静音

  7. 在此考虑 ORM

于 2013-11-15T15:35:48.753 回答