问题是:在2.2.1中分叉和调用GC时,内存重复。这个问题的主要问题是,当操作大量数据(范围为3GB)时,我的机器只能在一个分叉后被杀死。
我们编写了一个小程序来重现该问题(参见附件)。
程序实例化一个对象,然后分成两个进程。 在子进程中调用GC。 内存分配(由/ proc / pid / smaps给出)从共享变为私有,从而表明内存消耗加倍。
这是程序的输出(大小以mb为单位):
https://bugs.ruby-lang.org/issues/10559#change-50245
我们已经使用ruby 1.9.3,2.1.3和2.2.1(最新版)在Ubuntu 14.04上测试了该程序。测试已经在新安装的Ubuntu机器上进行,因此没有其他软件参与其中。
我们还试图分叉10个孩子并看到内存消耗增加了10倍,这个问题只发生在运行GC之后。
问题:这个问题的根源是什么(Ruby,内核,Ubuntu)以及可以用它做什么?
程序的源代码可以在这里找到:https://bugs.ruby-lang.org/issues/10559#change-50245
编辑:
这是我工作的代码。
def memory_object( size)
count = size/20
count.times do
result << "%20.18f" % rand
end
return result
end
big_memory = memory_object( 1000 * 1000* 30)
pid = fork do
big_memory_1 = memory_object( 1000 * 1000*30)
sleep( 1)
STDOUT.flush
exit!
end
Process.wait( pid)
如果运行上面的代码并使用linux上的smaps监视共享内存,你会发现在子进程中创建新对象的那一刻,整个内存变得私密但不应该因为我我甚至没有修改原始对象。然而,有趣的是,如果附加到数组的字符串是如下所示创建的,那么一切都表现正常。
result << rand.to_s
我怀疑这是因为底部版本产生的垃圾更少。但即使我在前几次强制GC之前,它仍然会发生。我怀疑这是因为一切都在GC堆上分配,实际上已经修改了,这导致了写时复制。有可能吗?