从CFC返回查询的内存含义

时间:2010-03-02 16:18:21

标签: coldfusion cfc

我在ColdFusion中编写了一个数据库加载脚本,我遇到了一个问题,即脚本内存缓慢耗尽。我用< cfthread>将每个表加载分成了自己的线程。当内存下降到50%以下时,我正在调用垃圾收集器(确保在gc()调用之间有30秒,以防止垃圾收集器占用内存)。

我创建了一个CFC来保存脚本所需的所有查询。该脚本调用适当的CFC函数,然后返回查询,其中一些查询大小超过2 MB。当我在活动线程的内存页面的详细信息视图中查看服务器监视器时,看起来我的CFC在内存中保留了查询的副本,即使我对查询变量进行了操作并且变量在最后超出了范围功能。另外,我在我的帖子中有一个内存查询的副本。所以我在内存中留下了两个查询副本。这真的发生了什么?如果是,我如何从内存中删除一个查询副本?

2 个答案:

答案 0 :(得分:11)

这里有很多潜在的问题,但我会尝试强调一些最重要的事情供你考虑:

  1. 为什么是线程?你需要线程吗?在某种程度上,你可能会为了自己的利益而修补过多。
  2. 手动强制垃圾收集不一定是个好主意。调整JVM以自动执行其垃圾收集,但也不要过度使用它。垃圾收集往往很昂贵,如果运行频繁,可能会影响应用程序的性能。
  3. 您如何实例化您的CFC?如果您在查询的每个请求上实例化CFC,那么随着时间的推移,您将遇到RAM问题,内存泄漏缓慢,因为CFC会过快地加载到RAM中以防止垃圾收集。你最好的选择是让它成为一个单身人士。 (即,将其设置为应用范围)。
  4. 请注意,变量不变量(据我所知)会在变量停止使用后自动释放内存。内存仍然是保留的,虽然它可能会被标记为短命代码的一部分,以便它(可能?)更快地被清理。但这并不保证任何事情。
  5. 如果您正在查看活动线程,那么在请求结束之前也不会清除查询 - 不一定是函数调用的结束。看起来不耐烦会激励你在函数调用完成后立即判断查询会立即死亡。
  6. ColdFusion queries are passed by reference,而非价值。在内存中获取2个查询副本应该是不可能的,除非你以某种方式使用duplicate()或类似函数来显式复制查询。
  7. 查询可能会从cfreturn语句返回指向查询的指针。在完成引用它的所有进程之前,不会清除该查询。因此,如果它将查询传递给其他进程,则不会将查询清除内存。例如,如果将该查询设置为会话变量,那么该指针在该会话变量消失之前不会移动到任何地方,无论您多久尝试强制进行垃圾收集。

    只需要考虑几件事。

答案 1 :(得分:0)

我在处理大型数据插入时遇到了类似的问题,其中每一行都需要涉及多个CFC的大量处理。似乎由< cfquery>创建的JDBC ResultSet,Statement和Connection引用一直持续到请求结束。这意味着将查询变量置零不会影响内存使用量。我解决这个问题的方法是对CFC函数进行网关调用以处理100行,然后该函数对接下来的100行等进行另一个网关调用,直到处理完所有行为止。因为每个单独的网关调用实际上都会退出,所以它会释放它的所有句柄并恢复内存。