Vla*_*eev 10 memory haskell memory-management ffi
正如库文档所说CString创建的newCString必须通过free函数释放.我一直在期待CString创建它时需要一些内存,当它被释放时free内存使用会下降,但它没有!这是示例代码:
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)
Run Code Online (Sandbox Code Playgroud)
当程序停在(1)时,htop程序显示内存使用量大约为410M - 这没关系.我按回车键,程序在第(2)行停止,但内存使用率仍为410M,尽管cs已经是freed!
这怎么可能?用C编写的类似程序就像它应该的那样.我在这里错过了什么?
问题是free只向垃圾收集器指示它现在可以收集字符串.这实际上并没有强制垃圾收集器运行 - 它只是表明CString现在是垃圾.根据堆压力启发式,仍然由GC决定何时运行.
您可以通过直接呼叫强制主要收集,这会立即将内存减少到5M左右.performGCfree
例如这个程序:
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)
Run Code Online (Sandbox Code Playgroud)
行为符合预期,具有以下内存配置文件 - 第一个红点是调用performGC,立即解除分配字符串.然后程序在大约5M左右徘徊直到终止.
