2012-10-24 56 views
3

我需要一个大型的数据列表,当在特定位置引用时,这些数据列表将计算(从文件加载和/或在尚未生成的情况下生成它)并保留以供将来使用。这是由绑定到函数的惰性列表驱动的。这些“块”有时会被加载,但之后从未真正被使用过,同时仍然在代码中被有效地引用,所以GC不会接受它们。Haskell惰性卸载

由于RAM快速填满,我想懒惰地卸载这些块一段时间后,他们什么都不用。这可能吗?

+0

你所说的“懒卸”是什么意思?直到最后一刻才卸载? –

回答

2

您可以通过使用unsafeInterleaveIO读取数据块,并定期通过该列表会并消除了未使用的很长一段时间(或者大块的引用实现这个:使用弱指针作为@nponeccop建议在评论),但我会选择一些不依赖GC来管理块的内存(因为可预测的内存使用情况对您很重要)。

例如:

import Data.HashTable.IO 

type ChunkMap = BasicHashTable ChunkId (Maybe Chunk) 

newChunkMap :: IO ChunkMap 
getChunk :: ChunkMap -> IO Chunk 
freeUnusedChunks :: ChunkMap -> IO() 

其中getChunk分配用于与mallocfreeUnusedChunks丢失块存储器通过表和free小号未使用组块去。

你甚至可以运行在单独的线程freeUnusedChunks

freeThread = forever $ do 
       withChunkMapLock $ do 
        freeUnusedChunks map 
        threadDelay 5000000 
+0

我怎么知道哪些不被使用? – kvanberendonck

+1

将时间戳与每个块关联并在每次访问时对其进行更新。然后,您可以将最后N个时间戳保留在循环缓冲区中,或者使用'freeUnusedChunks'计算它们。 –

+2

弱指针(来自'base'的'System.Mem.Weak')怎么办?它们在这里适合吗? – nponeccop