1

PDFファイルのディレクトリをループし、それぞれのサムネイルを作成するために使用している次の関数があります。

<cffunction name="createThumbnails" returntype="Void" output="false">
    <cfscript>
        //  CONSTANTs
        var _PDF_PATH = APPLICATION.PDFSource & "\PDFs";

        //  Set defaults for private variables
        var _qPDFDir = QueryNew("");
        var _documentId = 0;
        var _sourceFilePath = "";
        var _sku = "";
        var _tempImageFilePath = "";
    </cfscript>

    <!--- Retrieve a list of file names in the directory of unprocessed PDF files --->
    <cfdirectory
        action="list"
        directory="#_PDF_PATH#"
        name="_qPDFDir"
        filter="*.pdf"
        type="file"
        sort="datelastmodified DESC"
        listinfo="name" />

    <!--- Loop through the list of file names in the directory of unprocessed non-PDF files --->
    <cfloop query="_qPDFDir" endrow="500">
        <cfset _sourceFilePath = _PDF_PATH & "\" & name />

        <cfif FileExists(_sourceFilePath) AND IsPDFFile(_sourceFilePath)>
            <cftry>
                <cfpdf
                    action="thumbnail"
                    source="#_sourceFilePath#"
                    destination="#APPLICATION.TempDir#"
                    format="png"
                    scale="100"
                    resolution="high"
                    overwrite="true"
                    pages="1" />

                <cfcatch>
                    <cfscript>
                        FileMove(
                            _sourceFilePath,
                            _PDF_PATH & "\NonFunctioning\"
                            );
                    </cfscript>
               </cfcatch>
            </cftry>

            <cfscript>
                _documentId =
                    REQUEST.UDFLib.File.getFileNameWithoutExtension(name);
                _tempImageFilePath =
                        APPLICATION.TempDir
                    &   "\"
                    &   _documentId
                    &   "_page_1.png";

                if  (FileExists(_tempImageFilePath)) {
                    _sku = getSkuFromDocumentId(_documentId);

                    if  (Len(_sku)) {
                        CreateObject(
                            "component",
                            "cfc.products.Product"
                            ).setClientId(
                                getClientId()
                                ).setId(
                                    _sku
                                    ).createThumbnails(
                                        sourcePath = _tempImageFilePath,
                                        deleteSourceFile = true
                                        );

                        FileMove(
                            _sourceFilePath,
                            APPLICATION.ProcessedPDFDir
                            );
                    }
                }
            </cfscript>
        </cfif>
    </cfloop>

    <cfreturn />
</cffunction>

一部のコードは、私がやりたいことではありません。つまり、ファイルを「NonFunctioning」ディレクトリに移動しますが、ビジネス ルールで必要です。

私が理解しようとしているのは、この関数の実行時にメモリを使い果たすのをどのように回避できるかということです。

で、約148個のファイルを処理した後endrow="500"、エラーで爆撃しました。java.lang.OutOfMemoryError: GC overhead limit exceeded

また、タスク マネージャー (Windows) で jrun.exe プロセスを監視すると、メモリがどんどん増えていくのがわかります。

この関数のパフォーマンスを改善して、メモリが食い尽くされるのを防ぐ方法はありますか?

4

1 に答える 1

0

ループでオブジェクトを作成しています。オブジェクトを作成するたびに、CF はページの実行が終了するまでメモリを保持し、その後メモリを解放します。

  1. ループの外側でオブジェクトをインスタンス化して変数に保存し、ループ内でオブジェクトを再利用します。
  2. 単一のパスですべてのファイルを処理しないでください (スティーブが提案したように) ブロックで処理してから、新しい要求 (cfhttp など) を作成し、処理ページを再度呼び出します。これにより、最初のパスで使用されたメモリが解放されます。
于 2013-07-29T09:29:31.963 に答える