我在haskell中实现了一个服务器进程,它充当一个简单的内存数据库.客户端进程可以连接然后添加和检索数据.该服务使用的内存比我预期的多,而且我试图解决原因.
我最粗略的指标是linux"top".当我开始这个过程时,我看到"VIRT"图像大小约为27MB.在运行客户端以插入60,000个数据项后,我看到图像大小为~124MB.
我最初看到运行流程来捕获GC统计数据(+ RTS -S)
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
28296 8388 9172 0.00 0.00 0.00 0.32 0 0 (Gen: 1)
Run Code Online (Sandbox Code Playgroud)
并且在添加60k项目时,我看到实时字节平滑增长
...
532940 14964 63672180 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
532316 7704 63668672 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
530512 9648 63677028 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
531936 10796 63686488 0.00 0.00 23.51 31.96 0 0 (Gen: 0)
423260 10047016 63680532 0.03 0.03 23.53 31.99 0 0 (Gen: 1)
531864 6996 63693396 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531852 9160 63703536 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531888 9572 63711876 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531928 9716 63720128 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531856 9640 63728052 0.00 0.00 23.55 32.02 0 0 (Gen: 0)
529632 9280 63735824 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
527948 8304 63742524 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
528248 7152 63749180 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
528240 6384 63756176 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
341100 10050336 63731152 0.03 0.03 23.58 32.35 0 0 (Gen: 1)
5080 10049728 63705868 0.03 0.03 23.61 32.70 0 0 (Gen: 1)
Run Code Online (Sandbox Code Playgroud)
这似乎告诉我堆有大约63MB的实时数据.这可能与顶部的数字一致,当您添加堆栈空间,代码空间,GC开销等时.
所以我试图使用堆分析器来计算出这63MB的内容.结果令人困惑.使用"+ RTS -h"运行,并查看生成的hp文件,最后一个和最大的快照具有:
containers-0.3.0.0:Data.Map.Bin 1820400
bytestring-0.9.1.7:Data.ByteString.Internal.PS 1336160
main:KV.Store.Memory.KeyTree 831972
main:KV.Types.KF_1 750328
base:GHC.ForeignPtr.PlainPtr 534464
base:Data.Maybe.Just 494832
THUNK 587140
Run Code Online (Sandbox Code Playgroud)
快照中的所有其他数字都比这小得多.添加这些内容会使峰值内存使用量达到~6MB,如图表输出所示:
为什么这与GC统计中显示的实时字节不一致?很难看出我的数据结构如何需要63MB,而分析器说它们不是.记忆在哪里?
感谢您提供此任何提示或指示.
蒂姆
例如,您应该使用 hp2ps 来获取正在发生的情况的图形视图。查看原始 hp 文件很困难。