ozd*_*ies 1 ruby memory memory-management
过去几天我一直在研究一个涉及阅读大文件的项目.具体而言,它逐行读取它们以解析数据以插入数据库.
在对这些文件运行测试时,我发现对于一个400MB的文件,Ruby分配了超过1.2GB的内存; 大约是文件自身数量的3倍.更令人不安的是,一旦记忆被记录下来,Ruby就不想让大部分内存消失了.手动运行GC只能恢复大约三分之一的内存,意味着分成行的400MB文件占用超过800MB的内存.
这真让我感到困惑,我想知道是否有什么我做错了.这是我的代码复制问题:
text = File.read("somefile.txt").split("\n")
Run Code Online (Sandbox Code Playgroud)
我没有看到数组中的行如何在内存中加倍.
在另一种情况下,填充一个包含1000万个字符的数组会导致每1字节数据的内存比例达到40字节,尽管我已经准备好将其计入字符串元数据.
作为参考,我在Windows 8上使用Ruby 2.1.5p273 [i386-mingw32].
此外,在我得到答案之前告诉我以另一种方式阅读线路:我已经知道一些替代方案.这只是关于内存消耗的问题.
Ruby中的所有东西都是一个对象,它在C中是一个RVALUE(一个描述对象的结构并保存一个指向为其值分配的内存的指针),IIRC在64位机器上是40个字节,加上堆内存用于值RVALUE.
红宝石"堆"(未分配存储器的堆),它是一块内存,其存储右值.堆有N个插槽,其中1个插槽可以容纳一个RVALUE.填满堆时,Ruby会运行GC以尝试释放插槽,如果不能,则会分配另一个堆来保存其他RVALUE.一旦分配了Ruby就很难释放堆,因为在收集它之前它必须是完全空的,并且Ruby不断地分配新对象.
一般来说,你应该避免专门分配大量不可释放的对象,因为你最终会分配多个RVALUE堆,而Ruby则很难放弃.