Nei*_*ell 19 garbage-collection haskell ghc
鉴于该计划:
import Language.Haskell.Exts.Annotated -- from haskell-src-exts
import System.Mem
import System.IO
import Control.Exception
main :: IO ()
main = do
evaluate $ length $ show $ fromParseResult $ parseFileContents $ "data C = C {a :: F {- " ++ replicate 400000 'd' ++ " -} }"
performGC
performGC
performGC
Run Code Online (Sandbox Code Playgroud)
使用GHC 7.0.3,当我运行时:
$ ghc --make Temp.hs -rtsopts && Temp.exe +RTS -G1 -S
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
...
29463264 64 8380480 0.00 0.00 0.64 0.85 0 0 (Gen: 0)
20 56 8380472 0.00 0.00 0.64 0.86 0 0 (Gen: 0)
0 56 8380472 0.00 0.00 0.64 0.87 0 0 (Gen: 0)
42256 780 33452 0.00 0.00 0.64 0.88 0 0 (Gen: 0)
0 0.00 0.00
Run Code Online (Sandbox Code Playgroud)
该performGC
调用似乎留下了8Mb的内存,即使看起来所有的内存都应该死了.怎么会?
(没有-G1
我在最后看到10Mb直播,我也无法解释.)
Don*_*art 18
这就是我所看到的(在print
最后一次插入之后performGC
,以便在事情发生时帮助标记).
524288 524296 32381000 0.00 0.00 1.15 1.95 0 0 (Gen: 0)
524288 524296 31856824 0.00 0.00 1.16 1.96 0 0 (Gen: 0)
368248 808 1032992 0.00 0.02 1.16 1.99 0 0 (Gen: 1)
0 808 1032992 0.00 0.00 1.16 1.99 0 0 (Gen: 1)
"performed!"
39464 2200 1058952 0.00 0.00 1.16 1.99 0 0 (Gen: 1)
22264 1560 1075992 0.00 0.00 1.16 2.00 0 0 (Gen: 0)
0 0.00 0.00
Run Code Online (Sandbox Code Playgroud)
所以在GC之后,堆上仍然有1M(没有-G1).使用-G1我看到:
34340656 20520040 20524800 0.10 0.12 0.76 0.85 0 0 (Gen: 0)
41697072 24917800 24922560 0.12 0.14 0.91 1.01 0 0 (Gen: 0)
70790776 800 2081568 0.00 0.02 1.04 1.20 0 0 (Gen: 0)
0 800 2081568 0.00 0.00 1.04 1.20 0 0 (Gen: 0)
"performed!"
39464 2184 1058952 0.00 0.00 1.05 1.21 0 0 (Gen: 0)
22264 2856 43784 0.00 0.00 1.05 1.21 0 0 (Gen: 0)
0 0.00 0.00
Run Code Online (Sandbox Code Playgroud)
所以大约2M.这是在x86_64/Linux上.
让我们考虑一下STG机器存储模型,看看堆上是否有其他东西.
可能存在于1M的空间中的事情:
[]
字符串常量,小型Int
和Char
池,以及库中的东西,stdin
MVar?main
.根据经验,这个略低于1M的数字似乎是GHC二进制文件的默认"足迹".这也是我在其他程序中看到的内容(例如,枪战程序最小的足迹永远不会低于900K).
也许剖析器可以说些什么.这是-hT
配置文件(不需要配置文件库),我在最后插入一个最小的忙循环以排出尾部:
$ ./A +RTS -K10M -S -hT -i0.001
Run Code Online (Sandbox Code Playgroud)
此图表中的结果:
胜利!看看坐在那里的~1M线程堆栈对象!
我不知道如何让TSO变小.
生成上图的代码:
import Language.Haskell.Exts.Annotated -- from haskell-src-exts
import System.Mem
import System.IO
import Data.Int
import Control.Exception
main :: IO ()
main = do
evaluate $ length $ show $ fromParseResult
$ parseFileContents
$ "data C = C {a :: F {- " ++ replicate 400000 'd' ++ " -} }"
performGC
performGC
print "performed!"
performGC
-- busy loop so we can sample what's left on the heap.
let go :: Int32 -> IO ()
go 0 = return ()
go n = go $! n-1
go (maxBound :: Int32)
Run Code Online (Sandbox Code Playgroud)