我遇到ColdFusion堆的问题。这是我正在尝试的一个小例子应用程序。我想在cfinvoke
调用init
方法后,它会销毁组件本地的所有变量。但显然事实并非如此。该应用程序的工作原理如下,但如果我在index.cfm
中向循环添加零,则会中断。堆中存储的是什么原因造成的?有办法解决这个问题吗?
index.cfm:
<cfloop from="1" to="1000" index="i">
<cfinvoke component="test" method="init" returnvariable="x">
</cfloop>
<cfoutput><p>#x#</p></cfoutput>
test.cfc:
<cfcomponent output="false">
<cffunction name="init" returntype="string">
<cfset var test = structNew()>
<cfloop from="1" to="1000" index="i">
<cfset test[i] = i>
</cfloop>
<cfreturn Now()>
</cffunction>
</cfcomponent>
以下是错误消息:
SEVERE: Servlet.service() for servlet CfmServlet threw exception
javax.servlet.ServletException: ROOT CAUSE:
java.lang.OutOfMemoryError: Java heap space`
任何帮助都将不胜感激。
答案 0 :(得分:3)
这是一个已知问题,目前无法解决这个问题。 CF似乎没有正确处理垃圾收集。据我所知,在请求完成之前,它不会破坏和释放组件使用的内存。
因此,根据您的组件具有多少属性,将确定在您收到堆错误之前可以创建多少属性。
我知道这对你的问题没有帮助,但至少现在你可以采取措施来阻止它。
答案 1 :(得分:2)
rio747是正确的,在请求结束之前内存不会释放,因此您只是内存不足。我冒昧地说你可以运行它并得到错误,删除0它会运行; java垃圾收集正在运行,但直到请求结束。
解决问题的唯一方法是不在单个请求中创建任意数量的对象(可能需要更多信息来说明为什么需要这样做?)或者增加coldfusion可用的内存量。
我认为这不是一个问题或CF没有正确处理垃圾收集;从java的角度来看,只要该请求处于活动状态,该对象仍然可以被使用和引用。我的意思是,你对cfinvoke及其工作方式是正确的,但这并不意味着jvm实际上可以在这些内存位置上运行垃圾收集,直到请求结束。
答案 2 :(得分:0)
我刚刚发布了一个新的博客文章,其中显示了如果您的内存低于某个阈值,您可以如何进行程序化垃圾收集。希望它有所帮助: -