我有一个cfc方法,它正在循环遍历列表并通过cfhttp进行一系列SOAP调用。然后将结果插入到数据库中。
这个过程本身运作良好,问题在于Java内存会缓慢填满,并最终停止工作(具体取决于返回记录中的元素数量)。没有错误或任何可见的东西,它就会停止。如果我通过Coldfusion管理界面查看应用程序日志文件,我会看到以下一种或两种错误:
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 - dumping freeMemory -656条记录- 总记录数=10656
- 98173 - fm = 160.579734802 - dumping freeMemory -35条记录- 总记录数=35
- 99111 - fm = 176.218482971 - dumping freeMemory -0条记录- 总记录数=0
- 100998 - fm = 194.708694458 - dumping freeMemory -185条记录- 总记录数=185
- 101811 - fm = 160.61415863 - dumping freeMemory -2500条记录 - fm = 112.862670898 - dumping freeMemory -2500条记录 - fm = 86.2071380615 - dumping freeMemory -2500条记录 - fm = 52.9639358521 - dumping freeMemory -1064条记录- 总记录数=8564
- 105014 - fm = 56.1721343994 - dumping freeMemory -14条记录- 总记录数=14
- 105992 - fm = 73.0022964478 - dumping freeMemory -14条记录- 总记录数=14
- 107539 - fm = 75.9522399902 - dumping freeMemory -93条记录- 总记录数=93
- 107580 - fm = 58.345199585 - dumping freeMemory -2500条记录