我有一个 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 - 倾倒 freeMemory = 10966 条记录 - 共 106 条记录
- 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 -2500 条记录 = 总共 85640 条记录
- 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 条记录