我需要有一个大的数据列表,当在特定位置引用时计算(从文件加载,和/或如果尚未生成,则生成它)并将其保留以备将来使用。这由绑定到函数的惰性列表提供支持。这些“块”有时会被加载,但在那之后从未真正使用过,同时仍然在代码中有效地引用,因此 GC 不会接收到它们。
由于 RAM 很快就会被填满,我想在一段时间后懒惰地卸载这些块,因为它们没有被任何东西使用。这可能吗?
我需要有一个大的数据列表,当在特定位置引用时计算(从文件加载,和/或如果尚未生成,则生成它)并将其保留以备将来使用。这由绑定到函数的惰性列表提供支持。这些“块”有时会被加载,但在那之后从未真正使用过,同时仍然在代码中有效地引用,因此 GC 不会接收到它们。
由于 RAM 很快就会被填满,我想在一段时间后懒惰地卸载这些块,因为它们没有被任何东西使用。这可能吗?
您可以通过使用unsafeInterleaveIO
读取块并定期浏览列表并删除对长时间未使用的块的引用来实现这一点(或者:使用@nponeccop在评论中建议的弱指针),但我会去使用不依赖 GC 来管理块内存的东西(因为可预测的内存使用对您很重要)。
例如:
import Data.HashTable.IO
type ChunkMap = BasicHashTable ChunkId (Maybe Chunk)
newChunkMap :: IO ChunkMap
getChunk :: ChunkMap -> IO Chunk
freeUnusedChunks :: ChunkMap -> IO ()
wheregetChunk
为丢失的块分配内存,malloc
并freeUnusedChunks
遍历表和free
未使用的块。
您甚至可以freeUnusedChunks
在单独的线程中运行:
freeThread = forever $ do
withChunkMapLock $ do
freeUnusedChunks map
threadDelay 5000000