在Ruby中,堆栈上存储了什么?

在Ruby中,堆栈上存储了什么?,ruby,variables,memory,heap-memory,stack-memory,Ruby,Variables,Memory,Heap Memory,Stack Memory,Ruby是否分配堆上的所有内容,或者是否存在在堆栈上存储内容的实例?我的印象是,所有变量基本上都在堆栈上,并且包含对堆上对象的透明引用。我的想法正确吗?这个实现是特定的吗 另外,如果变量是在堆栈上分配的,并且只包含隐藏指针,那么变量本身(不考虑它们指向的对象)消耗多少字节 编辑: 之所以问这个问题,是因为我试图弄清楚光纤的4kB堆栈限制是否会成为未来的一个问题。似乎(在MRI 1.9.3中)每个变量本身消耗一个字节,并且与光纤相关的轻微开销将可用堆栈大小减少了几个字节 此代码将在4045次迭代中

Ruby是否分配堆上的所有内容,或者是否存在在堆栈上存储内容的实例?我的印象是,所有变量基本上都在堆栈上,并且包含对堆上对象的透明引用。我的想法正确吗?这个实现是特定的吗

另外,如果变量是在堆栈上分配的,并且只包含隐藏指针,那么变量本身(不考虑它们指向的对象)消耗多少字节

编辑:

之所以问这个问题,是因为我试图弄清楚光纤的4kB堆栈限制是否会成为未来的一个问题。似乎(在MRI 1.9.3中)每个变量本身消耗一个字节,并且与光纤相关的轻微开销将可用堆栈大小减少了几个字节

此代码将在4045次迭代中失败:

count = 0
loop do
  count += 1
  puts count
  varlist = String.new
  count.times do |i|
    varlist += "a#{i} = 1\n"
  end
  s = "fiber = Fiber.new do \n #{varlist} \n end \n fiber.resume"
  eval(s)
end

这取决于Ruby实现

例如,Ruby 2.0 MRI(大多数系统上的典型版本)将其所有对象存储在堆中。小对象(如短字符串)可以完全放入堆中。对于大型对象,Ruby将在堆外malloc额外的内存

看到和

这里有一个很长的描述:

“对象在内存中占用的全部空间不会存储在插槽中。相反,每个插槽都是一个固定大小的小空间,可以将其视为Ruby解释器的句柄和内存中的一个位置。这个位置位于Ruby堆本身之外,包含对象的真正“肉”。需要明确的是,如果您有一个50MB的字符串,那么50MB的数据存储在Ruby堆之外。如果您真的想知道50MB的故事,那么它的空间实际上是由C中的malloc命令(正如good ol'Ruby是用C编写的)分配的,然后存储在系统堆上。Ruby堆中的插槽只包含对系统堆上包含50MB数据的内存位置的引用。”

“Ruby有自己的堆管理,它实际上由几个“Ruby堆”组成,用于管理Ruby程序执行期间创建的对象;这与操作系统的系统堆是分开的。每个单独的Ruby堆都包含插槽,每个插槽只能引用一个对象

另一个好的来源是“”,它链接到“”处的幻灯片

“作为一种垃圾收集语言,Ruby采取了简单的方法,将所有东西都放在堆上”

纤维 在Ruby中,光纤是特殊的,因为每根光纤都有自己的小堆栈

“与其他无堆栈轻型并发模型不同,每根光纤都有一个小的4KB堆栈。这使光纤能够从光纤块中的深度嵌套函数调用中暂停。”

您可能对一种长期运行的动态纤维堆叠尺寸调整方法感兴趣

如果您对现实世界中的解决方案更感兴趣,那么功能请求作者建议这样一种解决方法:“重构操作,该操作需要一个大堆栈在单独的线程中运行,然后在thread.value上阻塞。”


您还可以考虑编写一个自定义版本的Ruby,您自己选择了FixyMaxeToxSoqLoLosiTosixSoad和FielyVMyStaskIg大小,在<代码> CONT.C.<代码>源文件中。该文件还显示了如何分配、释放光纤堆栈等。

属性位于堆上。方法中的变量在堆栈上。除非您从函数返回局部变量,或从闭包中使用它,或将其存储在其他地方,否则“堆栈”的概念实际上没有意义,因为对象的寿命超过了函数调用的寿命。@GregHewgill在函数调用的情况下是这样的,其最大大小为4kB。我想知道我是否会因为这么小的堆叠而对光纤产生问题。哦,这对于你的问题来说是非常重要的。你可能想特别提到这一点。似乎有相互矛盾的说法。“Ruby MRI(大多数系统上的典型配置)将其所有对象都放在堆上”和“此位置存在于Ruby堆之外,并包含对象的真正“肉”。要清楚,如果您有50MB字符串,则50MB的数据存储在Ruby堆之外”。所以堆上只存储对象引用?@codeObserver我添加了更多细节,可能对您的评论有用,并为GC添加了一个新链接。看看你怎么想。