gpt4 book ai didi

haskell - 惰性 IO - 字符串未被垃圾收集?

转载 作者:行者123 更新时间:2023-12-02 02:24:03 27 4
gpt4 key购买 nike

我目前正在尝试将 XML 文件的内容读入 Map Int (Map Int String) 并且它工作得很好(使用 HaXml)。但是,我对程序的内存消耗不满意,问题似乎出在垃圾回收上。

这是我用来读取 XML 文件的代码:

type TextFile = Map Int (Map Int String)

buildTextFile :: String -> IO TextFile
buildTextFile filename = do content <- readFile filename
let doc = xmlParse filename content
con = docContent (posInNewCxt filename Nothing) doc
return $ buildTF con

我的猜测content即使在返回后也保存在内存中,虽然它不需要是(当然它也可以是doc con)。我得出这个结论是因为对于非常大的 XML 文件,内存消耗会迅速上升,虽然生成的 TextFile 只是单例映射的单例映射(使用特殊的测试文件,一般它是不同的,当然).所以最后,我有一个 Map Int StringMap,里面只有一个字符串,但是内存消耗高达 19 MB。

使用严格的应用程序 ($!) 或使用 Data.Text 而不是 TextFile 中的 String 不会不要改变任何东西。

所以我的问题是:有什么方法可以告诉编译器字符串 content(或 doccon)不是不再需要它并且它可以被垃圾收集?

更一般地说:如何在不进行所有猜测的情况下找出问题的真正来源?

编辑:正如 FUZxxl 所建议的,我尝试使用 deepseq 并更改了 buildTextFile 的第二行,如下所示:

let doc = content `deepseq` xmlParse filename content

不幸的是,这并没有真正改变任何东西(或者我用错了吗?)...

最佳答案

不要猜测什么在消耗内存,要确定

第一步是确定哪些类型消耗的内存最多。您可以在 SO 上看到大量堆分析示例或阅读 GHC manual .

强制计算

如果问题是惰性求值(您正在构建一个可以计算 XML 文档类型并将字符串也留在堆中的堆上 thunk),那么使用 rnf 和 seq:

buildTextFile :: String -> IO TextFile
buildTextFile filename = do content <- readFile filename
let doc = xmlParse filename content
con = docContent (posInNewCxt filename Nothing) doc
res = buildTF con
return $ rnf res `seq` res

或者只使用 bang 模式 (!res = buildTF con),无论哪种方式都应该强制 thunk 并允许 GC 收集 String

关于haskell - 惰性 IO - 字符串未被垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6764075/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com