debugging堆概要分析中不显示的内存泄漏

我正在接收和处理JSON请求的Haskell守护进程。 虽然守护进程的操作是复杂的,但主要的结构是故意保持简单:其内部状态只是一个具有数据结构的IORef ,所有线程都在这个IORef上执行primefaces操作。 然后有一些线程在触发器上取值a做一些事情。

问题是守护进程正在泄漏内存,我找不到原因。 这当然与请求有关:当守护进程每秒获得几个请求时,它会泄漏1MB / s的东西(如Linux工具所报告的)。 内存消耗稳步增加。 没有请求,内存消耗保持不变。

令我感到困惑的是,这些都没有显示在GHC分析中。 要么我在configuration文件参数中丢失了某些内容,或者内存被别的东西占用了:

+RTS -hc -xt -p运行+RTS -hc -xt -p

探查器输出的截图

运行+RTS -hr -xt -p

探查器输出的截图

在此testing运行期间,守护进程随后消耗超过1GB。 所以分析数据显然不符合实际消耗的内存数量级。 (据我所知,RTS,GC和configuration本身增加了实际的内存消耗,但是这种差别太大了,并不符合不断增长的消耗。)

我已经尝试过处理rnf中守护进程的所有状态数据,以及parsing的JSON请求(以避免部分JSONstring被保留在某处),但是没有太多成功。

任何意见或build议表示欢迎。

更新:守护进程在没有-threaded情况下运行,所以没有OS级的线程。

GC统计信息比堆分析更接近Linux报告的数字:

  Alloc Copied Live GC GC TOT TOT Page Flts bytes bytes bytes user elap user elap [...] 5476616 44504 2505736 0.00 0.00 23.21 410.03 0 0 (Gen: 0) 35499296 41624 2603032 0.00 0.00 23.26 410.25 0 0 (Gen: 0) 51841800 46848 2701592 0.00 0.00 23.32 410.49 0 0 (Gen: 0) 31259144 36416 2612088 0.00 0.00 23.40 410.61 0 0 (Gen: 0) 53433632 51976 2742664 0.00 0.00 23.49 412.05 0 0 (Gen: 0) 48142768 50928 2784744 0.00 0.00 23.54 412.49 0 0 (Gen: 0) [...] 

更新2:我发现问题的由来,内存泄漏是由handleToFd引起的(请参阅unix库的这个问题 )。 我只是想知道如何更有效地查明这种泄漏(可能发生在外国代码中)。

虽然我不熟悉Haskell守护进程本身,但回答“如何更有效地查明这种泄漏”的问题,可能会使用

valgrind --leak-check=yes haskelldaemon (如果你用debugging信息编译的话更好)

或者,如果共享库中发生泄漏,请尝试

LD_PRELOAD="yourlibrary.so" valgrind your-executable