【发布时间】:2015-03-24 09:49:02
【问题描述】:
我正在尝试遍历维度为 12000 * 20 的 2-D 数组,并且我不断收到 java.lang.OutOfMemoryError。
最初我认为这可能是因为堆大小,所以我增加了堆大小,但我仍然遇到同样的错误。所以我运行了一个这样的垃圾收集器:
<cflock name="checkMemory" type="exclusive" timeout="1" throwontimeout="yes">
<cfset objSystem = CreateObject( "java", "java.lang.System" )>
<cfset objSystem.gc()>
</cflock>
然后我转储了850MB 附近的空闲内存:
<cfset runtime = CreateObject("java","java.lang.Runtime").getRuntime()>
<cfset freeMemory = runtime.freeMemory()>
<cfdump var="#freeMemory#" label="free">
我在这里尝试创建一个 XML 变量,并且在循环时出现堆错误:
<cfxml variable="variables.XML">
<cfoutput>
<ROWS>
<cfloop from="3" to="#arrayLen(local.array)#" index="i" step="1">
<ROW>
<cfloop from="1" to="#arrayLen(local.array[2])#" index="j" step="1">
<#ucase(local.array[2][j])#>
<![CDATA[#trim(local.array[i][j])#]]>
</#ucase(local.array[2][j])#>
</cfloop>
</ROW>
</cfloop>
</ROWS>
</cfoutput>
</cfxml>
这是堆栈跟踪:
java.lang.OutOfMemoryError 在 java.io.WinNTFileSystem.getBooleanAttributes(Native Method) 在 java.io.File.exists(File.java:733) 在 Coldfusion.xml.XmlProcessor.getSourceURL(XmlProcessor.java:246) 在 冷融合.xml.XmlProcessor.parse(XmlProcessor.java:155) 在 Coldfusion.tagext.lang.XmlTag.doEndTag(XmlTag.java:85) 在 cffeeds2ecfc1003675922$funcDEMO1._factor8(C:\component\abc.cfc:1235) 在 cffeeds2ecfc1003675922$funcDEMO1.runFunction(C:\component\abc.cfc:1192) 在coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) 在 Coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) 在 Coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) 在 Coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55) 在coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321) 在 Coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220) 在 Coldfusion.runtime.CfJspPage._invokeUDF(CfJspPage.java:2582) 在 cffeeds2ecfc1003675922$funcDEMO.runFunction(\component\abc.cfc:935) 在 Coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) 在 Coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) 在 Coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) 在 Coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55) 在coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321) 在 Coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:517) 在 Coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:496) 在 Coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:355) 在 Coldfusion.filter.ComponentFilter.invoke(ComponentFilter.java:188) 在 Coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:374) 在 Coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48) 在coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) 在coldfusion.filter.PathFilter.invoke(PathFilter.java:94) 在 Coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) 在 Coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) 在coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) 在 Coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) 在 Coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) 在 Coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) 在 冷融合.xml.rpc.CFCServlet.invoke(CFCServlet.java:139) 在 Coldfusion.xml.rpc.CFCServlet.doPost(CFCServlet.java:290) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:760) 在 org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:853) 在 Coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) 在 jrun.servlet.FilterChain.doFilter(FilterChain.java:86) 在 com.intergral.fusionreactor.filter.FusionReactorFilter.i(FusionReactorFilter.java:566) 在 com.intergral.fusionreactor.filter.FusionReactorFilter.c(FusionReactorFilter.java:258) 在 com.intergral.fusionreactor.filter.FusionReactorFilter.doFilter(FusionReactorFilter.java:164) 在 jrun.servlet.FilterChain.doFilter(FilterChain.java:94) 在 Coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42) 在 Coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) 在 jrun.servlet.FilterChain.doFilter(FilterChain.java:94) 在 jrun.servlet.FilterChain.service(FilterChain.java:101) 在 jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) 在 jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) 在 jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286) 在 jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543) 在 jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203) 在 jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320) 在 jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428) 在 jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266) 在 jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
有没有更好的解决方案来避免这样的循环或解决这个错误?
我在本地创建了一个 cfm 页面并在其中添加了一些变量,如下所示:
<cfset runtime = CreateObject("java","java.lang.Runtime").getRuntime()>
<cfset freeMemory = runtime.freeMemory()>
<cfset totalMemory = runtime.totalMemory()>
<cfset maxMemory = runtime.maxMemory()>
<cfdump var="#freeMemory#" label="free">
<cfdump var="#totalMemory#" label="total">
<cfdump var="#maxMemory#" label="max">
每次我刷新此页面时,可用内存大小都会减少,直到我运行 GC。我仍在试图弄清楚为什么会这样。有这方面的建议吗?
请帮忙。 提前致谢。
【问题讨论】:
-
此处代码的相关部分将是您缩写为
//Some operation的位。不可能在没有看到代码的情况下评论如何使代码对内存使用更加友好。 -
@AdamCameron 我已经更新了我的问题。
-
所以
array2实际上不是array的子数组,它只是一个相同长度的不同区域,定义了所有的XML节点?展示如何创建数组变量以确认这一点可能会有所帮助。当您填充 array2 时,我很想只使用 UCase,从而减少 12000 * 20 * 2 函数调用。 -
我可能会先构建字符串,然后将其转换为 XML,而不是使用我过去曾遇到过内存问题的 CFXML。创建此 XML 后,您将如何处理它?也同意 Duncan:您不需要多次使用 ucase() 相同的字符串。可能也使用 StringBuilder,而不是 String。
-
如果您将 CFOUTPUT 移到循环外部,这样您就不会分别调用 240,00 次,会发生什么情况。在构建大字符串时,我更喜欢将字符串片段转储到一维数组中,然后在最后使用 ArrayToList(Array, "")。然后使用最终生成的单个字符串执行 CFXML,而不是在 CFXML 块中执行所有操作。
标签: coldfusion heap-memory coldfusion-9 cfloop