【发布时间】:2012-04-25 23:40:02
【问题描述】:
前几天我尝试将资源池和 HDBC 放在一起,但注意到每个查询的内存都在不断增加。然后我用尽可能少的函数编写了一个简单的测试代码,得到了这个:
data SQL = SQL (Pool Connection)
check :: SQL -> IO ()
check (SQL pool) = do res <- query' pool "show status like 'Threads_conn%'" []
threadDelay 100000
check (SQL pool)
整个代码: http://upaste.me/40f2229cef7157f
对于检查函数的每次递归,程序使用的内存越来越多。结果不应该在新的递归调用中被垃圾收集,还是会保留在内存中,直到程序退出该函数以防“我们需要它”?
【问题讨论】:
-
在堆填满之前不会进行垃圾收集。如果稍微限制堆会发生什么?查看
./yourprogram +RTS -h的输出,了解如何执行此操作。 -
我用
./program +RTS -H4096K限制了堆,和以前一样,程序会为每个递归调用建立内存。 -
HDBC 有可能将终结器附加到外部对象,这些终结器在主要 GC 发生之前不会被释放。由于 GC 不知道外来对象的大小,因此它不会将其视为对堆压力的贡献,从而导致 GC 次数减少。 HDBC 也可能只是没有释放所需的资源。试试 explciit
performGC -
尝试用明确的
forever重写... -
performGC和forever都不能解决当前的问题。我开始认为这是图书馆 HDBC 本身的问题。也可能是因为我通过线程引用了池,所以 GC 没有按需要收集信息。
标签: haskell memory-leaks hdbc