我有一个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个列表可供浏览
最佳答案
这不是Java无法很好地管理GC的情况,而是您没有以某种方式管理要放入(或从〜取出)内存的内容,以至于垃圾收集器可以清理它们。您正在(尝试〜)对待症状而不是这里的问题。
看一下内存中将要存储的内容,以及为什么您期望被GC的内容没有被GC的原因。可能是因为您在一个共享范围内(意外地)引用了某些东西,或者类似的东西。但是,在Java之上使用ColdFusion对此类问题进行故障排除有点不明智。
但是,当您强制执行GC时,请勿尝试“解决”未发生GC的“问题”,请解决导致内存不足的问题。 b)在您认为应该是GC时不可用。