gpt4 book ai didi

ruby - 为什么 Ruby 使用如此多的内存来存储大型数组?

转载 作者:太空宇宙 更新时间:2023-11-03 17:10:13 25 4
gpt4 key购买 nike

过去几天我一直在从事一个项目,该项目涉及读取较大的文件。具体来说,它逐行读取它们以解析数据以插入到数据库中。

在对这些文件进行测试时,我发现对于一个 400MB 的文件,Ruby 分配了超过 1.2GB 的内存;大约是文件本身占用量的 3 倍。更麻烦的是,一旦内存被占用,Ruby 就不想让大部分内存消失。手动运行 GC 只能回收它分配的大约三分之一的内存,这意味着一个 400MB 的文件分成几行占用超过 800MB 的内存。

这真的让我很困惑,我想知道我是否做错了什么。这是我复制问题的代码:

text = File.read("somefile.txt").split("\n")

我没有看到数组中的行是如何将其内存大小加倍的。

在另一种情况下,用 1000 万个字符填充一个数组会导致每 1 字节数据占用 40 字节的内存,尽管我已准备好将此考虑到字符串元数据。

作为引用,我在 Windows 8 上使用 Ruby 2.1.5p273 [i386-mingw32]。

此外,在我得到答案之前告诉我以另一种方式阅读台词:我已经知道一些替代方案。这只是一个关于内存消耗的问题。

最佳答案

Ruby 中的一切都是一个对象,在 C 中是一个 RVALUE(一个描述对象并保存指向为其值分配的内存的指针的结构),IIRC 在 64 位机器上是 40 字节,加上堆内存为 RVALUE 的值。

Ruby 在“堆”(不是 堆)中分配内存,这是存储 RVALUE 的内存块。一个堆有 N 个槽,其中 1 个槽可以容纳一个 RVALUE。当您填满一个堆时,Ruby 将运行 GC 以尝试释放插槽,如果不能,它将分配另一个堆来容纳额外的 RVALUE。很难让 Ruby 在分配后释放堆,因为它必须完全清空才能被收集,而且 Ruby 不断分配新对象。

一般来说,您应该特别避免分配大量不可释放的对象,因为您最终会分配多个 RVALUE 堆,Ruby 很难放弃这些堆。

关于ruby - 为什么 Ruby 使用如此多的内存来存储大型数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29138489/

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