Mam obliczenia wewnątrz ST, który przydziela pamięć za pomocą Data.Vector.Unboxed.Mutable. Wektor nigdy nie jest czytany ani zapisywany, ani też żadne odniesienie nie zostało do niego zachowane poza runST (zgodnie z moją najlepszą wiedzą). Problem polega na tym, że kiedy wielokrotnie wykonuję obliczenia ST, czasami wydaje mi się, że przechowuję pamięć dla wektora.Haskell: Wyciek pamięci ze ST/GC nie zbiera?
statystyki Przeznaczenie:
5,435,386,768 bytes allocated in the heap
5,313,968 bytes copied during GC
134,364,780 bytes maximum residency (14 sample(s))
3,160,340 bytes maximum slop
518 MB total memory in use (0 MB lost due to fragmentation)
Tutaj nazywam runST 20x z różnymi wartościami dla moich obliczeń i wektorem 128MB (ponownie - nieużywany, nie zwrócone lub odwoływać poza ST). Maksymalna rezydencja wygląda dobrze, w zasadzie tylko mój wektor plus kilka MB innych rzeczy. Ale całkowite użycie pamięci wskazuje, że mam cztery aktywne obrazy w tym samym czasie. To idealnie pasuje do wielkości wektora, dla 256 MB otrzymujemy 1030 MB zgodnie z oczekiwaniami.
W wektorze 1GB zabrakło pamięci (4x1GB + obciążenie> 32-bitowe). Nie rozumiem, dlaczego RTS zachowuje pozornie nieużywaną, nieprzywiązaną pamięć wokół, zamiast po prostu ją GC'ing, przynajmniej w miejscu, w którym alokacja w przeciwnym razie by zawiodła.
Biegając z + RTS -S ujawnia, co następuje:
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
134940616 13056 134353540 0.00 0.00 0.09 0.19 0 0 (Gen: 1)
583416 6756 134347504 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
518020 17396 134349640 0.00 0.00 0.09 0.19 0 0 (Gen: 1)
521104 13032 134359988 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
520972 1344 134360752 0.00 0.00 0.09 0.19 0 0 (Gen: 0)
521100 828 134360684 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520812 592 134360528 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520936 1344 134361324 0.00 0.00 0.10 0.19 0 0 (Gen: 0)
520788 1480 134361476 0.00 0.00 0.10 0.20 0 0 (Gen: 0)
134438548 5964 268673908 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
586300 3084 268667168 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
517840 952 268666340 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520920 544 268666164 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520780 428 268666048 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520820 2908 268668524 0.00 0.00 0.19 0.38 0 0 (Gen: 0)
520732 1788 268668636 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
521076 564 268668492 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520532 712 268668640 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520764 956 268668884 0.00 0.00 0.19 0.39 0 0 (Gen: 0)
520816 420 268668348 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520948 1332 268669260 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520784 616 268668544 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
521416 836 268668764 0.00 0.00 0.20 0.39 0 0 (Gen: 0)
520488 1240 268669168 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520824 1608 268669536 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520688 1276 268669204 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520252 1332 268669260 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
520672 1000 268668928 0.00 0.00 0.20 0.40 0 0 (Gen: 0)
134553500 5640 402973292 0.00 0.00 0.29 0.58 0 0 (Gen: 0)
586776 2644 402966160 0.00 0.00 0.29 0.58 0 0 (Gen: 0)
518064 26784 134342772 0.00 0.00 0.29 0.58 0 0 (Gen: 1)
520828 3120 134343528 0.00 0.00 0.29 0.59 0 0 (Gen: 0)
521108 756 134342668 0.00 0.00 0.30 0.59 0 0 (Gen: 0)
Tutaj wydaje się, mamy przekraczającej ~ 128MB 'Żywe bajty.'
Profil +RTS -hy
zasadzie tylko mówi, że przeznaczyć 128MB:
http://imageshack.us/a/img69/7765/45q8.png
Próbowałem odtwarzając to zachowanie w prostszym programem, ale nawet z replikacji dokładną konfigurację z ST, czytnik zawierającej wektor, tym samym monad/struktura programu itp. prosty program testowy tego nie pokazuje. Upraszczając mój wielki program, zachowanie również zatrzymuje się w końcu podczas usuwania pozornie zupełnie niepowiązanego kodu.
Qs:
- Am I naprawdę utrzymując ten wektor około 4 razy na 20?
- Jeśli tak, to w jaki sposób mogę powiedzieć, że
+RTS -Hy
imaximum residency
twierdzą, że nie jestem i co mogę zrobić, aby zatrzymać to zachowanie? - Jeśli nie, dlaczego Haskell nie zgłasza go i brakuje przestrzeni adresowej/pamięci i co mogę zrobić, aby zatrzymać to zachowanie?
Dzięki!
Używana pamięć jest zwykle dwukrotnie większa od maksymalnej rezydentności lub więcej, w zależności od wzoru przydziału i odbioru. Tak więc całkowita wykorzystana pamięć 518 MB nie jest sama w sobie alarmująca. Spróbuj powiedzieć GHC, że na dysku jest tylko tyle pamięci, na przykład '$ ./foo + RTS -M256M', aby zmusić go do wcześniejszego pobrania. Ale "ani odniesienie zachowane do niego poza runST" może być nieprawdziwe, naprawdę można mieć przeciek. W takim przypadku trzeba by zobaczyć kod. –
@DanielFischer 518MB ma rozmiar ~ 4x. Czy awaria pamięci z wektorem 1GB nie wskaże, że GHC * nie może * zebrać pamięci? + RTS -M256M kończy się niepowodzeniem z "Heap exhausted". Wektor jest tworzony, umieszczony w środowisku Reader, to wszystko. Nic więcej, nie jestem pewien, co jeszcze mogę zrobić, aby uniknąć wycieku odniesień po opuszczeniu ST/Reader. Tak jak powiedziałem, nie mogę odtworzyć tego problemu w prostszym programie. Wydaje się raczej losowy. – NBFGRTW
Cóż, 4 × może się zdarzyć, biorąc pod uwagę prawy/zły schemat alokacji. Awaria poza pamięcią może wskazywać, że GHC nie wie, że powinna się teraz zbierać, ale biorąc pod uwagę, że '-M256M' powoduje, że" stos wyczerpany ", wygląda bardziej jak coś ma odniesienie do bestii. –