Próbuję zmodyfikować monadę Data.Binary.PutM w transformator monad. Zacząłem więc przez changin To definicja zDlaczego zmiana monady Data.Binary.Put w transformator powoduje wyciek pamięci?
newtype PutM a = Put { unPut :: PairS a }
do
newtype PutM a = Put { unPut :: Identity (PairS a) }
Wtedy oczywiście zmieniłem implementacje zamian i >> = funkcje:
Od:
return a = Put $ PairS a mempty
{-# INLINE return #-}
m >>= k = Put $
let PairS a w = unPut m
PairS b w1 = unPut (k a)
in PairS b (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $
let PairS _ w = unPut m
PairS b w1 = unPut k
in PairS b (w `mappend` w1)
{-# INLINE (>>) #-}
Do:
return a = Put $! return $! PairS a mempty
{-# INLINE return #-}
m >>= k = Put $!
do PairS a w <- unPut m
PairS b w1 <- unPut (k a)
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>=) #-}
m >> k = Put $!
do PairS _ w <- unPut m
PairS b w1 <- unPut k
return $! PairS b $! (w `mappend` w1)
{-# INLINE (>>) #-}
Tak jakby monada PutM była tylko monadą pisarza. Niestety to (again) spowodowało wyciek przestrzeni. Dla mnie jest jasne (czy jest?), Że ghc odkłada gdzieś ocenę, ale próbowałem umieścić $!
zamiast $
wszędzie, jak sugerowały niektóre tutoriale, ale to nie pomogło. Ponadto nie jestem pewien, w jaki sposób profiler pamięci jest przydatny, jeśli to, co mi pokazuje, jest następujące:
.
I pod względem kompletności, jest to profil pamięć uzyskać przy użyciu oryginalnego Data.Binary.Put monady:
Zainteresowanych here jest kod używam go przetestować i linia używam skompilować, uruchomić i stworzyć profil pamięci to:
ghc -auto-all -fforce-recomp -O2 --make test5.hs && ./test5 +RTS -hT && hp2ps -c test5.hp && okular test5.ps
mam nadzieję, że nie jestem przykry ktoś przez mojego sagi pytań wycieków pamięci. Uważam, że w Internecie nie ma zbyt wielu dobrych zasobów na ten temat, które pozostawiają po sobie ślad.
Dzięki za spojrzenie.
Cześć Peter - Nie jestem przekonany, masz przeciek „przestrzeń” w Data.Binary tjniepoprawny uchwyt danych zatrzymujący gromadzenie śmieci. Myślę, że budowanie ogromnego profilu pamięci jest spowodowane tym, że struktura danych (drzewo) nie jest przesyłana strumieniowo - wszystko musi znajdować się w pamięci (oraz podobnie duży wyjściowy ByteString), dopóki nie zakończy się serializacja. Moją intuicją jest problem - drzewo - nie Data.Binary. –
Witam @ Stephen, zapomniałem wspomnieć, że jeśli używam oryginalnej Monady Data.Binary.Put (tej bez Tożsamości), to ładnie się strumieniuje (brak zauważalnego zwiększenia pamięci). Rozumiem, że jeśli pamięć została skonsumowana wyłącznie przez strukturę drzewa, wzrost pamięci przejawia się w obu przypadkach. –
Czy możesz przesłać nam więcej kodu? – fuz