使用RTSStats进行不一致的分配

时间:2018-02-15 22:12:54

标签: haskell ghc

我正在测量功能分配,我遇到了一些我不太了解的行为。这是一个简单的再现:

module Main where

import GHC.Stats (GCDetails(..), RTSStats(..), getRTSStats)
import System.Mem (performGC)

main :: IO ()
main = loop 100
  where
    loop 0 = return ()
    loop n = runOtherThing n >> loop (n-1)

runOtherThing :: Int -> IO ()
runOtherThing n = do
    performGC
    stats <- getRTSStats
    putStrLn $ show (n `mod` 15) ++ ": "
            ++ show (gcdetails_allocated_bytes (gc stats))
            ++ " num: " ++ show (gcs stats)
    --putStrLn "inflate allocation"

哪个输出:

$ ghc Main.hs
$ ./Main +RTS -s
...
14: 4648 num: 12
13: 4744 num: 13
12: 4744 num: 14
11: 4744 num: 15
10: 4744 num: 16
9: 8704 num: 17
8: 4648 num: 18
7: 4648 num: 19
6: 4648 num: 20
5: 4648 num: 21
4: 4648 num: 22
3: 4648 num: 23
2: 4648 num: 24
1: 4648 num: 25
0: 4648 num: 26
14: 4648 num: 27
13: 4744 num: 28
12: 4744 num: 29
11: 4744 num: 30
10: 4744 num: 31
9: 8704 num: 32
8: 4648 num: 33
7: 4648 num: 34
6: 4648 num: 35
5: 4648 num: 36
4: 4648 num: 37
3: 4648 num: 38
2: 4648 num: 39
1: 4648 num: 40
0: 4648 num: 41
...

我正在使用8.2.1和新版本RTSStats,但它也适用于旧的GCStats

每15个GC,分配额外的~4k字节(可能是一页?)。左边的数字是循环编号mod 15,因此您无需计算,只需在输出中查找以9开头的行。右边是程序执行的GC总数,表明我们没有丢失任何数据。

我做了很多更改,而且数字总是精确到15。你可以取消注释inflate allocation行,这就行了。还报告了额外的4k字节。即使你添加了多行来扩大分配,它也不会改变。

这让我相信额外的字节与我的代码无关。或者至少,不是由我分配数据触发的。

我真的不知道该怎么做。为了测量分配,我可能会制定一个合理的策略来检测和删除这些数据点。但是有可能完全避免这种情况吗?什么是15?

0 个答案:

没有答案