52700.fb2
seconds
Рис. 10.13: Опять двойка
sum2 :: [Int] -> (Int, Int)
sum2 = iter (0, 0)
where iter ! c
[]
= c
iter ! c
(x:xs) = iter (tick x c) xs
Теперь снова посмотрим на профиль:
$ ghc --make leak2.hs -rtsopts -prof -auto-all
$ ./leak2 6 +RTS -K30m -hc
(500000,500000)
$ hp2ps -e80mm -c leak2.hp
Мы видим (рис. 10.14), что память резко подскакивает и остаётся постоянной. Но теперь показатели
измеряются не в мегабайтах, а в килобайтах. Мы справились. Остальные флаги hX позволяют наблюдать за
разными специфическими объектами в куче. Мы можем узнать сколько памяти приходится на разные модули
(hm), сколько памяти приходится на разные конструкторы (hd), на разные типы замыканий (hy).
Поиск источников внезапной остановки
case-выражения и декомпозиция в аргументах функции могут стать источником очень неприятных оши-
бок. Программа прошла проверку типов, завелась и вот уже работает-работает как вдруг мы видим на экране:
*** Exception: Prelude. head: empty list
или
*** Exception: Maybe. fromJust: Nothing
И совсем не понятно откуда эта ошибка. В каком модуле сидит эта функция. Может мы её импортировали
из чужой библиотеки или написали сами. Как раз для таких случаев в GHC предусмотрен специальный флаг
xc.
Посмотрим на выполнение такой программы:
Статистика выполнения программы | 171
leak2 6 +RTS -hc
5,944 bytes x seconds
Fri Jun 1 21:51 2012
bytes
30k
(51)PINNED
25k
20k
(72)GHC.IO.Encoding.CAF
15k
(59)GHC.IO.Handle.FD.CAF
10k
(58)GHC.Conc.Signal.CAF
5k
0k
0.0
0.0
0.0
0.1
0.1