对象内存分配

时间:2014-02-18 05:06:31

标签: ruby object memory-management

我想知道Ruby中的内存分配是如何工作的。

在Ruby中,我们可以打开一个类定义并添加更多实例变量/方法。在这种情况下,新对象比现有实例需要更多内存。它如何在内部跟踪分配给实例的内存?

例如,我们有以下类定义:

class MyClass
    def myMethod
        @a = 5
    end
end

我们创建了MyClass的实例:

m = MyClass.new
m.myMethod

此时,m将被分配一些内存。现在,我们打开类定义并添加另一个实例变量b

class MyClass
    def mySecondMethod
        @b = 5
    end
end

此新方法mySecondMethod和实例变量b也可在m的现有实例Myclass中使用。

调用mySecondMethod实例化并初始化b

m.mySecondMethod

Ruby如何内部管理内存?它是否重新分配了例如m的内存块,还是保留了一些指向新分配内存的指针?

2 个答案:

答案 0 :(得分:9)

答案取决于实际的实施。在这里,我假设您询问的是MRI

Ruby对象分配在heap上。在谈论对象分配时,没有stack的概念。

堆被分成,每个包含16kb。每个页面都划分为固定大小插槽,可以容纳Ruby对象。页面可以容纳~408个对象,因为每个对象(RVALUE结构)占用40个字节。

所有这些都由VM管理(即YARV)。

ruby heap layout 来源:http://timetobleed.com/garbage-collection-slides-from-la-ruby-conference/

关于您的示例,变量只是将引用保存到对象,因此m实际上指向到已分配的{{1}对象。

在内部备份MyClass的C结构(RClass)包含一个指向表的指针,该表具有用户定义的方法,如MyClass和指向具有名称的表的指针其对象具有的实例变量。

每个对象(由RObject类备份,因为Object类是所有对象的默认根目录)内部包含pointer to the values of its instance variables

由于语言的动态特性以及方法查找在运行时发生的事实,新定义的#mySecondMethod可用。

答案 1 :(得分:1)

你的第二个猜测是正确的。 Ruby对象维护指向堆内存的指针。

但请注意,在您的示例中,由于mySecondMethod从未在您的对象m上调用,因此未为@b设置/初始化该实例变量m

最有可能帮助你的事情是,首先,使用Ruby进行更多练习,并了解其类和对象的成语是如何工作的。然后,我建议查看一些关于Ruby垃圾收集器的资源,如this very good and recent article