ora*_*ips 5 coldfusion memory-leaks
一直以来,我能够在ColdFusion 9.01上使用以下代码生成Java Heap Space OutOfMemory异常(尚未尝试过早期版本):
<cfset uuidGenerator = createObject("java", "java.util.UUID")>
<cfset transient = structNew()>
<cfloop from="1" to="100000" index="index">
<cfset transient[uuidGenerator.randomUUID().toString()] = true>
</cfloop>
Run Code Online (Sandbox Code Playgroud)
上面的代码使用Java UUID类,因为它比ColdFusion更快.请求后结构本身不存在(即它不在某些持久范围内application).
作为测试,我在初始化服务器之后生成堆转储.然后我多次运行这段代码,看看终身代通过jConsole填充.之后,我运行另一个堆转储.使用Eclipse Memory Analysis Tool的Leak报告,我可以看到一个根据的大对象coldfusion.util.Key.
我在这里问,希望其他人遇到类似的问题,如果是这样的话,他们已经做了什么来解决它.
这不是理想的解决方案,但在 Adobe 内部修复内存泄漏之前,您可以访问 Coldfusion.util.Key 对象上的私有成员 ConcurrentHasMap 并手动清除它。
我们设置了一个计划任务,每晚执行一次,然后立即执行 GC。
将其编译为 JAR 文件并将其放在 ColdFusion 类路径中的某个位置。
import coldfusion.util.Key;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
class KeyEx
{
public KeyEx()
{
}
public void resetCache(Object k)
{
try
{
Field f = Key.class.getDeclaredField("keys");
f.setAccessible(true);
ConcurrentHashMap chm = (ConcurrentHashMap)f.get(k);
chm.clear();
}
catch (Exception ex)
{
System.out.println("ZOMG something went epically wrong!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以简单地在 Coldfusion 中实例化新的 KeyEx 对象,并调用在 Coldfusion.util.Key 单例中传递的 ResetCache。
<cfset keys = createObject("java", "coldfusion.util.Key") />
<cfset x = createObject("java", "KeyEx").init() />
<cfset x.resetCache(keys) />
Run Code Online (Sandbox Code Playgroud)