2012-05-09 14 views
10

Kitaplık belgeleri olarak newCString ile oluşturulan CString işlevi free işleviyle serbest bırakılmalıdır. Ben CString oluşturulduğunda biraz bellek alır ve free bellek kullanımı ile serbest bırakıldığında aşağı gideceğini bekliyordum, ama yoktu! İşte örnek kod: Program (1), htop programı bellek kullanımı 410m etrafında bir yerde olduğunu gösterdi durdunewCString ile ayrılmış bellek boşaltma

module Main where 

import Foreign 
import Foreign.C.String 
import System.IO 

wait = do 
    putStr "Press enter" >> hFlush stdout 
    _ <- getLine 
    return() 

main = do 
    let s = concat $ replicate 1000000 ['0'..'9'] 
    cs <- newCString s 
    cs `seq` wait -- (1) 

    free cs 
    wait -- (2) 

- bu sorun yok. Enter'a basıyorum ve program hat (2) 'de durur, ancak csfree d olmasına rağmen bellek kullanımı hala 410M'dir d!

Bu nasıl olabilir? C olarak yazılan benzer program gerektiği gibi davranır. Burada neyi özlüyorum?

+1

Hangi GHC sürümünü kullanıyorsunuz? Hafızaya işletim sistemine geri dönüş yeteneği sadece geçen sene GHC'ye eklendi. –

+0

'ghc --version' çıktıları The Glorious Glasgow Haskell Derleme Sistemi, sürüm 7.4.1' –

cevap

8

konu free sadece şimdi dize toplayabilir çöpçüyle gösterir olmasıdır. Bu aslında çöp toplayıcısını çalıştırmaya zorlamıyor - sadece CString'in artık çöp olduğunu gösteriyor. Yığın basıncı buluşlarına dayanarak, ne zaman çalışmayacağına karar vermek GC'ye kalmış durumda.

yapabilirsiniz kuvvet düz derhal öylesine 5M veya hafızayı azaltan free çağrısının, sonra performGC arayarak önemli bir koleksiyon.

E.g. Bu programı:

import Foreign 
import Foreign.C.String 
import System.IO 
import System.Mem 

wait = do 
    putStr "Press enter" >> hFlush stdout 
    _ <- getLine 
    return() 

main = do 
    let s = concat $ replicate 1000000 ['0'..'9'] 
    cs <- newCString s 
    cs `seq` wait -- (1) 

    free cs 
    performGC 
    wait -- (2) 

davranır aşağıdaki bellek profiliyle, beklendiği gibi - ilk kırmızı nokta hemen dize ayırmayı kaldırma performGC çağrısı vardır. Program sonlandırılana kadar 5M civarında gezer.

enter image description here

+0

Çok teşekkür ederim. Ghc’de malloc/'free''ın bu şekilde çalıştığını bilmiyordum. PerformGC'yi denedim ve gerçekten çalışıyor. Peki, bu soru C kütüphanesinin çalışmasına ne kadar iyi bağlandığımı test ettiğimde ortaya çıktı. Onları büyük miktarda C dizgisiyle test ettim ve hafızanın yayınlamadığını öğrenince şaşırdım. O ben performGC' gerçekten çalışıyor 'senin kanıtlarla iddia edemez sanırım –

+2

) Bu sır çözüldü gibi görünüyor, ama bu Gidip [kaynak] (http bakana kadar cevap neydi diye farz olduğunu: // hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/Foreign-Marshal-Alloc.html#free) - bu gibi görünüyor bana özgürdürler gerçekten ('serbest C işlevi arama) '. Bu, GC ile nasıl etkileşir? –

+2

Şüpheliyim çünkü bellek aslında GC işletim sistemine kadar GHC rts havuzundan işletim sistemine sunulmuyor. Böylece, Haskell'den hafıza bloğunu yeniden kullanabileceksiniz, sadece işletim sistemine henüz geri verilmiyor. –

İlgili konular