GHC's internal memory allocator never releases memory back to the OS
allocaBytes does not appear to free the memory after the computation has completed. For example, start ghci and run:
allocaBytes (100*1024*1024) $ \_ -> getLine
ghci's virtual memory usage will jump up by 100MB. When you press enter however, it does not drop back down.
restart ghci and try:
bracket (mallocBytes 100*1024*1024) free $ \_ -> getLine
This time when you press enter, the memory usage will drop back down to its pre mallocBytes usage.
This also happens for compiled programs.
Note: the above test will only alloc virtual memory since nothing is ever read into the malloc'd memory. The following test program will actually force the pages to be mapped. It results in the same broken behaviour with the addition that the resident size of ghci gets stuck high.
module Main where
import Control.Exception
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Data.Word
import System.IO
import System.Mem
test :: Int -> IO ()
test mb =
let size = mb * 1024 * 1024 in
do -- bracket (mallocBytes size) free $ wait size -- this version works
allocaBytes size $ wait size -- this version does not free the memory afterwards
performGC
wait :: Int -> Ptr Word8 -> IO ()
wait size p =
bracket (openBinaryFile "/dev/scsi/host0/bus0/target0/lun0/part1" ReadMode) (hClose) (\h -> hGetBuf h p size >> putStrLn "waiting..." >> getLine >> return ())
main =
do test 150
putStrLn "is it free?"
getLine
return ()
Trac metadata
Trac field | Value |
---|---|
Version | 6.4.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (FFI) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Linux |
Architecture | x86 |