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 に答える