为啥读取文件会占用整个文件的内存?

Posted

技术标签:

【中文标题】为啥读取文件会占用整个文件的内存?【英文标题】:Why reading of file takes memory for the whole file?为什么读取文件会占用整个文件的内存? 【发布时间】:2014-01-28 10:29:00 【问题描述】:

我正在这样做:

import qualified Data.ByteString.Lazy.Char8 as BS

main :: IO ()
main = do
    let filename = "sample.txt"    
    text <- BS.readFile filename
    let res = BS.take 1000 $ text
    print res

当我通过分析运行它时,它给了我:

162,048 bytes allocated in the heap
2,472 bytes copied during GC
59,688 bytes maximum residency (1 sample(s))
22,232 bytes maximum slop
156 MB total memory in use (0 MB lost due to fragmentation)

我读到的文件大约是 50Kbytes。为什么需要 60Kbytes 内存(最大驻留)?我也尝试过使用字符串和惰性文本。这是同一张照片。我认为 Haskell 以某种方式将整个文件读入内存,或者只是分配与文件长度一样多的内存。 我怎么能防止这种情况?我只想从中读取 N 个字节,不想浪费这么多内存。

【问题讨论】:

with runghc 占用 57M 但编译 ghc -O3 t.hs 仅占用`61,816 字节最大驻留`(最大实际内存使用量2M,我的sample.txt 是84M @josejuan 嗯,我无法重现您使用runghc 看到的行为。大文件对我来说大约需要 60K。而且我看不出它如何依赖于优化...... 【参考方案1】:

您的文件大小为 50K,但 readFile 通过 32k chunks 读取文件。所以你有一半的文件在内存中。除此之外,一些内存用于运行时系统、gc、print 中的中间惰性字符串等。所以 60K 最大驻留是可以的。

您可以尝试使用更大的文件,例如100M。您会看到最大居住数不会增加。

如果默认块大小不适合您,请尝试hGetSome

【讨论】:

以上是关于为啥读取文件会占用整个文件的内存?的主要内容,如果未能解决你的问题,请参考以下文章

在磁盘读取或写入时ntoskrnl占用cpu,请问如何解决啊,谢谢

使用内存映射文件读取大文件

Python读取文件内容的方法有几种

为啥分叉我的进程会导致文件被无限读取

从文件中读取的数据比文件大小占用更多的内存

如何逐行读取大文件?