【问题标题】:Memory implications of returning a query from a CFC从 CFC 返回查询的内存含义
【发布时间】:2010-03-02 16:18:21
【问题描述】:

我在 ColdFusion 中编写了一个数据库加载脚本,但我遇到了一个问题,即该脚本会慢慢耗尽内存。我已经使用 将每个表加载拆分到自己的线程中,并且当内存低于 50% 时调用垃圾收集器(确保在 gc() 调用之间有 30 秒,以防止垃圾收集器占用内存) .

我创建了一个 CFC 来保存脚本所需的所有查询。该脚本调用相应的 CFC 函数,然后返回查询,其中一些大小超过 2 MB。当我在活动线程的内存页面的详细信息视图中查看服务器监视器时,看起来我的 CFC 将查询的副本保留在内存中,即使我对查询变量进行了 varscoped 并且变量最后超出了范围的功能。此外,我在线程的内存中有一份查询副本。所以我只剩下内存中查询的两个副本。真的是这样吗?如果是,我怎样才能从内存中删除一个查询副本?

【问题讨论】:

标签: coldfusion cfc


【解决方案1】:

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

  1. 为什么是线程?你需要线程吗?在某些时候,您可能会为了自己的利益而进行过多的修补。
  2. 手动强制垃圾回收不一定是个好主意。调整 JVM 以自动执行其垃圾收集,但也不要过度。垃圾收集往往很昂贵,如果应用运行过于频繁,可能会影响应用的性能。
  3. 如何实例化 CFC?如果您在每次查询请求时都实例化 CFC,那么随着时间的推移,您将遇到 RAM 问题,由于 CFC 太快地加载到 RAM 中而导致垃圾收集跟不上,导致内存泄漏缓慢。你最好的选择是让它成为一个单例。 (即,将其设置为应用范围)。
  4. 请注意,对变量进行 var 作用域(据我所知)不会在变量停止使用后立即自动释放内存。内存仍然保留,尽管它可能以某种方式被标记为短命一代的一部分,以便(可能?)更快地清理它。但这并不能保证任何事情。
  5. 如果您正在查看活动线程,也有可能在请求结束之前查询不会被清除——不一定是函数调用结束。似乎不耐烦会促使您期望查询在函数调用完成后立即终止。
  6. ColdFusion queries are passed by reference,不是按值。在内存中获取 2 个查询副本应该是不可能的,除非您以某种方式使用 duplicate() 或类似的函数来显式复制查询。

查询可能会从您的 cfreturn 语句返回指向查询的指针。在所有进程完成引用它之前,不会清理该查询。因此,如果它将查询传递给其他进程,则不会将该查询从内存中清除。例如,如果您将该查询设置为会话变量,则该指针在该会话变量消失之前不会去任何地方,无论您尝试强制垃圾回收的频率如何。

只需考虑几件事。

【讨论】:

  • 很棒的答案。我并不期待试图解释这一切,但看起来我没有必要。 :-)
  • 谢谢。知道查询是通过引用传递的,这很有帮助。我无法在我的在线搜索中找到该信息。我为每个线程实例化一次 CFC。我正在执行多个线程,因为在请求完成之前,即使使用 gc(),内存似乎也没有被完全清理干净。看起来一个线程是它自己的请求,所以我对它进行了多线程清理。使用完查询变量后,我一直将它设置为空字符串,这似乎可以缓解一些内存问题。
  • 嗯,线程不会帮助您使用更少的内存,但它们确实可以确保您同时将更多的东西加载到内存中。此外,我质疑甚至想要垃圾收集器在请求仍在运行时暂停所有内容并进行清理是否明智。
  • 我阻塞了线程,以便一次只执行一个。所以是的,他们确实确保脚本使用更少的内存。我的测试证明了这一点。这样,我只需将一页添加到计划作业列表中,该作业就会启动将数据导入数据库的所有单独线程。在线程中间运行 gc() 的好处是线程运行时间很长,如果没有它,脚本的内存使用往往会导致服务器崩溃。
【解决方案2】:

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

【讨论】:

  • 非常有趣。我可能会试一试。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
相关资源
最近更新 更多