リストをループし、cfhttp を介して一連の SOAP 呼び出しを行う cfc メソッドがあります。次に、結果をデータベースに挿入します。
プロセス自体はうまく機能します。問題は、Java メモリがゆっくりといっぱいになり、最終的には (返されるレコード内の要素の数に応じて) 動作を停止することです。エラーや目に見えるものはなく、停止するだけです。coldfusion admin 経由でアプリケーション ログ ファイルを見ると、次のエラーのいずれかまたは両方が表示されます。
GC overhead limit exceeded The specific sequence of files included or processed is:
また
Java heap space The specific sequence of files included or processed is:
以下は、私が実行しているコードの簡略版です。
<cfsetting requesttimeout="3600">
<cfloop condition="thisPass lt 10">
<cfscript>
runtime = CreateObject("java","java.lang.Runtime").getRuntime();
objSystem = CreateObject( "java", "java.lang.System" );
soapBody = '';
soapResponse = '';
thisStruct = '';
lock scope='application' type='exclusive' timeout='60' {
//This is where I am trying to manage the memory and call garbage collection
try {
freeMemory = runtime.freeMemory()/1024/1024;
writeOutput("- fm = "&freeMemory);
if (freeMemory < 200){
objSystem.gc();
sleep(1000);
writeDump(' - dumping freeMemory');
}
}
catch(any error) {
writeDump(' - trying to dump GC as '&now()& ' freeMemory = '&freeMemory);
}
}
</cfscript>
<cfsavecontent variable="soapBody">
<?xml version="1.0" encoding="utf-8"?>
[ BUILD SOAP ENVELOP ]
</cfsavecontent>
<cfhttp url="[URL]" method="post" result="httpResponse"
timeout="600" resolveurl="false">
<cfhttpparam type="header" name="SOAPAction" value="[URL2]" />
<cfhttpparam type="xml" value="#trim( soapBody )#"/>
</cfhttp>
<cfscript>
soapBody = "";
soapResponse = httpResponse.fileContent;
soapResponse = xmlParse( soapResponse );
thisStruct = xmlSearch(soapResponse,'/soap:Envelope/soap:Body/')[1].xmlChildren[1].xmlChildren[1].xmlChildren;
writeOutput("-"&arrayLen(thisStruct)&' records');
getPageContext().getOut().flush();
if(arrayLen(thisStruct) == 2500){
thisPass = thisPass+1;
} else {
writeOutput("- total records = "&(2500*(thisPass-1))+arrayLen(thisStruct));
thisPass = 100; // since looping while thisPass lt 10 this should prevent the next iteration
}
</cfscript>
<cfloop from="1" to="#arrayLen(thisStruct)#" index="i">
[RUN PROC TO INSERT RECORDS]
</cfloop>
</cfloop>
GC は時々メモリを少し解放するようですが、信頼性はありません。GC() は、Java が未使用のメモリの一部を解放するための推奨事項にすぎないことを理解していますが、強制的にメモリを解放する方法がわかりません。どこかで漏れている可能性がありますが、私はそれを見ていません。私はこれが私が見過ごした明らかなものであることを望んでおり、私の Java の知識は非常に限られていることを認めます。
私のエラーを見ることができるJavaの第一人者はいますか?
更新:これは、メモリの減少を確認するのに役立つ場合の出力のサンプルです。
ループするリストは 236 個あります
- 88185 - fm = 293.564407349 -6 レコード - 合計レコード = 6
- 88389 - fm = 290.86995697 -116 レコード - 合計レコード = 116
- 88390 - fm = 308.382568359 -262 レコード - 合計レコード = 262
- 88839 - fm = 292.707099915 -2032 レコード - 合計レコード = 2032
- 91088 - fm = 290.711753845 -6 レコード - 合計レコード = 6
- 92998 - fm = 287.754066467 -5 レコード - 合計レコード = 5
- 95510 - fm = 309.919425964 -91 レコード - 合計レコード = 91
- 96478 - fm = 292.035064697 -1180 レコード - 合計レコード = 1180
- 96479 - fm = 259.001213074 -1113 レコード - 合計レコード = 1113
- 96480 - fm = 261.121406555 -110 レコード - 合計レコード = 110
- 96796 - fm = 267.235244751 -2 レコード - 合計レコード = 2
- 96799 - fm = 265.037582397 -0 レコード - 合計レコード = 0
- 97435 - fm = 263.589103699 -2500 レコード - fm = 227.629760742 -2500 レコード - fm = 200.85987854 -2500 レコード - fm = 202.156776428 -2500 レコード - fm = 166.366210938 - フリーメモリのダンプ -6 合計 60 レコード = 65
- 98173 - fm = 160.579734802 - freeMemory のダンプ -35 レコード - 合計レコード = 35
- 99111 - fm = 176.218482971 - freeMemory のダンプ -0 レコード - 合計レコード = 0
- 100998 - fm = 194.708694458 - freeMemory のダンプ -185 レコード - 合計レコード = 185
- 101811 - fm = 160.61415863 - freeMemory -2500 レコードのダンプ - fm = 112.862670898 - freeMemory -2500 レコードのダンプ - fm = 86.2071380615 - freeMemory -2500 レコードのダンプ - fm = 52.9639358521 - freeMemory -1064 レコードのダンプ - 合計 4 レコード = 85
- 105014 - fm = 56.1721343994 - freeMemory のダンプ -14 レコード - 合計レコード = 14
- 105992 - fm = 73.0022964478 - freeMemory のダンプ -14 レコード - 合計レコード = 14
- 107539 - fm = 75.9522399902 - freeMemory のダンプ -93 レコード - 合計レコード = 93
- 107580 - fm = 58.345199585 - freeMemory のダンプ -2500 レコード