这几乎可以肯定是垃圾收集 (GC),可能是更高一代(即主要 GC)。在创建大量长寿命垃圾的情况下,这些可能会导致严重暂停。
如果您想看到这种情况发生,您可以制作一个快速可执行文件并检查:
以tmp.hs开头:
module Main where
fibs = 1:1:zipWith (+) fibs (tail fibs)
main = print $ fibs !! 100000
使用ghc -rtsopts tmp.hs编译
使用./tmp +RTS -s运行
454,847,088 bytes allocated in the heap
230,044,816 bytes copied during GC
4,291,856 bytes maximum residency (226 sample(s))
18,080,904 bytes maximum slop
56 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 676 colls, 0 par 0.07s 0.07s 0.0001s 0.0023s
Gen 1 226 colls, 0 par 0.27s 0.28s 0.0012s 0.0084s
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.14s ( 0.14s elapsed)
GC time 0.34s ( 0.35s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.48s ( 0.49s elapsed)
%GC time 71.0% (71.6% elapsed)
Alloc rate 3,303,664,644 bytes per MUT second
Productivity 28.9% of total user, 28.8% of total elapsed
这表示 676 次次要垃圾回收和 226 次主要垃圾回收,第二代垃圾回收的完成时间比次要多约 12 倍。请注意,这只是第 10 万个数字,因此数字越大,停顿时间可能会更长。另请注意,GHCI 是一个解释器,因此会有相关的减速。
顺便说一句,我确实尝试在打开优化的情况下编译和运行这个示例。时间上没有明显差异,内存/GC特性几乎相同。