我需要有一个大的数据列表,当在特定位置引用时计算(从文件加载,和/或在尚未生成的情况下生成它)并保留以供将来使用。这由绑定到函数的惰性列表提供支持。这些“块”有时会加载但在此之后从未真正使用过,但仍然在代码中有效引用,因此GC不会接收它们。
由于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
使用malloc
和freeUnusedChunks
为缺少的块分配内存,并通过表和free
未使用的块。
您甚至可以在单独的帖子中运行freeUnusedChunks
:
freeThread = forever $ do
withChunkMapLock $ do
freeUnusedChunks map
threadDelay 5000000