gpt4 book ai didi

ruby - Ruby 的 fiber 4kB 堆栈大小的后果

转载 作者:数据小太阳 更新时间:2023-10-29 06:41:54 27 4
gpt4 key购买 nike

纤维对我来说是一个相对较新的概念。我知道每个光纤的堆栈大小限制为 4kB,我一直在阅读我应该“提防”这一点。这个限制在现实世界中的后果到底是什么?

编辑:

看来这个 4kB 的限制毕竟不是这样的障碍,它在光纤本身中需要大量的局部变量 (4,045) 才能引发 SystemStackError。

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

这不是最优雅的代码,但它似乎确实展示了纤程堆栈的局限性。似乎它只是返回值、局部变量(所有这些都包含对堆上对象的引用)和方法调用被放在堆栈上。我还没有测试从纤程调用的方法中的局部变量等是否是纤程堆栈的一部分。

编辑 2:

修改了上面的代码。看起来被调用方法中的变量等确实成为纤程堆栈的一部分。如果是这种情况,那么调用深度(即使没有递归)可能会成为一个更大的问题,因为方法本身可能比变量(它似乎是对堆上对象的透明引用)需要更多的堆栈空间。

以下代码在第 4,031 次迭代时失败,并指示被调用方法中的变量成为纤程堆栈的一部分:

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

编辑 3:

刚刚尝试在 Rubinius 2.0 上运行初始代码示例。它的纤程似乎没有 4kB 的堆栈限制,尽管超过大约 3,500 次迭代后它变得越来越慢并且明显变慢,并且在大约第 5,000 次迭代时它平均每秒迭代一次。我不知道 RBX 是否有限制,因为我在刚好超过 5,100 次迭代时退出执行。 RBX 使用的内存也比 MRI 1.9.3 多几倍。

JRuby 1.7 似乎也没有 4kB 的纤程堆栈大小,我不知道纤程是否有最大堆栈大小。我毫无问题地完成了第一个代码示例的 5,000 次迭代,尽管正如所料,JVM 消耗了几百 MB 的 RAM。

最佳答案

正如安东在他的回答中提到的,你在纤程中的内存密集型代码。可能(可能)占用大量内存的示例:

  • 大字符串(即:包含适当大小的 HTTP 响应的字符串)
  • 递归函数(堆栈级别太深!)
  • 流或类似流的对象:要非常小心流缓冲区;如果它们接近或超过 4k,您将开始看到一些非常奇怪的行为

关于ruby - Ruby 的 fiber 4kB 堆栈大小的后果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13638503/

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