Ruby Symbol#to_proc 在 1.9.2-p180 中泄漏引用?

2023-11-23

好的,这是我第二次尝试使用 Sinatra 应用程序调试内存问题。我相信这次我已经将其固定为简单的示例代码。

看来当我过滤数组时.map(&:some_method),它会导致该数组中的项目无法被垃圾收集。运行等效的.map{|x| x.some_method}完全没问题。

演示:给定一个简单的示例类:

class C
  def foo
    "foo"
  end
end

如果我在 IRB 中运行以下命令,它会正常收集:

ruby-1.9.2-p180 :001 > a = 10.times.map{C.new}
 => [...]
ruby-1.9.2-p180 :002 > b = a.map{|x| x.foo}
 => ["foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo"]
ruby-1.9.2-p180 :003 > ObjectSpace.each_object(C){}
 => 10
ruby-1.9.2-p180 :004 > a = nil
 => nil
ruby-1.9.2-p180 :005 > b = nil
 => nil
ruby-1.9.2-p180 :006 > GC.start
 => nil
ruby-1.9.2-p180 :007 > ObjectSpace.each_object(C){}
 => 0

所以不再存在对 C 的引用。好的。但替代map{|x| x.foo} with map(&:foo)(这被宣传为等效),它不会被收集:

ruby-1.9.2-p180 :001 > a = 10.times.map{C.new}
 => [...]
ruby-1.9.2-p180 :002 > b = a.map(&:foo)
 => ["foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo", "foo"]
ruby-1.9.2-p180 :003 > ObjectSpace.each_object(C){}
 => 10
ruby-1.9.2-p180 :004 > a = nil
 => nil
ruby-1.9.2-p180 :005 > b = nil
 => nil
ruby-1.9.2-p180 :006 > GC.start
 => nil
ruby-1.9.2-p180 :007 > ObjectSpace.each_object(C){}
 => 10
ruby-1.9.2-p180 :008 >

这是红宝石错误吗?我会尝试更多版本的 ruby​​ 来确定,但这似乎是一个明显的问题。有人知道我做错了什么吗?

Edit:

我在 1.8.7-p352 中尝试过,没有问题。 1.9.3-预览1does但仍然存在问题。错误报告是否正常,或者我做错了什么?

Edit2:格式化(为什么在每行之前放置四个空格会产生语法突出显示,而<pre>标签没有?)


As a.map(&:foo)应该完全等于a.map{|x| x.foo},看来您确实在这里遇到了 Ruby 代码中的错误。在(http://redmine.ruby-lang.org/)上提交错误报告不会有什么坏处,最糟糕的情况就是它被忽略。您可以通过提供针对该问题的补丁来减少出现这种情况的可能性。

EDIT:我打开了 IRB 并尝试了你的代码。我可以重现您所描述的问题ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]。但是,明确调用to_proc符号上没有遇到同样的问题:

irb(main):001:0> class C; def foo; end; end
=> nil
irb(main):002:0> a = 10.times.map { C.new }
=> [...]
irb(main):004:0> b = a.map(&:foo.to_proc)
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
irb(main):005:0> ObjectSpace.each_object(C){}
=> 10
irb(main):006:0> a = b = nil
=> nil
irb(main):007:0> GC.start
=> nil
irb(main):008:0> ObjectSpace.each_object(C){}
=> 0

看来我们面临着隐含的问题Symbol -> Proc在这里转换。也许稍后我会尝试深入研究 Ruby 源代码。如果是这样,我会及时通知您最新情况。

EDIT 2:

该问题的简单解决方法:

class Symbol
  def to_proc
    lambda { |x| x.send(self) }
  end
end

class C
  def foo; "foo"; end
end

a = 10.times.map { C.new }
b = a.map(&:foo)
p b
a = b = nil
GC.start
p ObjectSpace.each_object(C) {}

prints 0.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby Symbol#to_proc 在 1.9.2-p180 中泄漏引用? 的相关文章

随机推荐

  • WPF FlowDocument - 绝对字符位置

    我有一个 WPF RichTextBox 我正在其中输入一些文本 然后解析整个文本以进行处理 在此解析过程中 我获得了每个单词的开头和结尾的绝对字符位置 我想使用这些字符位置对某些单词应用格式 但是 我发现 FlowDocument 使用
  • 将 Dictionary 转换为匿名对象?

    首先 为了让事情更清楚 我将从顶部解释我的场景 我有一个具有以下签名的方法 public virtual void SendEmail String from List
  • 如何删除包含 GridView 的空 div

    在 ASP NET Gridviews 中生成一个表 该表生成一个父 div 容器 这可能会破坏 CSS 布局 因为无法将样式附加到生成的 div 有没有办法阻止 div 生成或对其应用样式 已询问此问题并标记为已解决here但MS只是说d
  • 在 main() 之外处理 argc 和 argv

    如果我想将用于处理命令行参数的大部分代码保留在 main 之外 以便组织和更具可读性的代码 那么最好的方法是什么 void main int argc char argv lots of code here I would like to
  • 引用没有强名称的程序集

    有没有办法在没有强名称的情况下引用库 当我在引用中添加对程序集的引用并重建解决方案时 一切都很好 但是当我从此程序集解决方案调用该类时 它不会构建 输出表明引用的程序集应该具有强名称 最好的解决方案是什么 强命名库并不可取 我认为您遇到的问
  • Json.Net 可以嵌入到可执行文件中吗?

    我设置了 嵌入互操作类型 属性Netwonsoft Json图书馆到true它返回一个错误 Cannot embed interop types from assembly c path packages Newtonsoft Json 9
  • 在 JSPX 文件中包含 JS 文件(JQuery)

    我正在 Eclipse 中创建一个动态 Web 项目 几乎从头开始 并创建了一个 JSPX 文件 将其放置在 我打算使用Jquery UI 可排序我发现使用 JSPX 只有第一个脚本在 Firefox 和 IE 中加载
  • 如何使用Opencv轮廓单向描述线点

    我正在使用opencvsfindContour找到描述由线 而不是多边形 组成的图像的点 如下所示 cv findContours src contours hierarchy cv RETR EXTERNAL cv CHAIN APPRO
  • 在 javascript 中迭代颜色

    我想列出 css 中使用的所有颜色的列表 但它们似乎以 16 进制格式存储 我认为这样的事情可能会起作用 但它并没有达到我想要的效果 for x x lt 100 x color x toString 16 在 JavaScript 中 您
  • 如何重新启动独立的 Adob​​e Air/Flex 应用程序

    如何让独立的 Adob e Air Flex 应用程序自行重启 它不适用于以下建议的解决方案 http www colettas org p 267 任何帮助都会很棒 Thanks 你好亲爱的我已经修复了 Flex 4 6 的这个方法 pa
  • 日期时间格式如 HH:mm 24 小时,不含 AM/PM

    我在这里搜索关于将 16 20 这样的字符串转换为 DateTime 类型而不丢失格式 我说我不想添加 dd MM yyy 或秒或 AM PM 因为 db 只是接受这种格式 我还尝试过文化 提前致谢 只需为您的日期时间提供日期格式即可 st
  • 如何使用谷歌材料图标作为类而不是 标签

    根据指南中的谷歌材料网站我们必须在 中使用材质图标i 标签 问题是如何将图标添加为很棒的字体 就像是 Class material icons face 代替 i class material icons face i 是的 您可以使用 a
  • Visual C++ 易失性

    Visual C 中 易失性 的 MSDN 文档表明 除了确保读取始终从内存中读取以及写入始终相应地写入之外 写入具有 释放语义 读取具有 获取语义 易失性 的 C 规范包括第二部分 不要进行疯狂的优化 但不包括第一部分 内存栅栏 Visu
  • 装饰器对代码的特定行而不是整个方法进行计时?

    让我们假设一个简单的方法 def test method a 1 b 10000 c 20000 sum1 sum range a b sum2 sum range b c return sum1 sum2 要使用装饰器计时此方法 一个简单
  • __LINE__ __FILE__ 或 qml 中的类似函数

    我正在尝试打印调用者函数 行号和文件名 而不会在 QML 中出于正常调试目的抛出错误 我可以打印调用者函数名称 如下所示 console log Caller Function Name arguments callee caller na
  • 以编程方式滚动 EditText

    我正在编写一个简单的凯撒加密活动 屏幕上有两个 EditText 一个是明文 一个是加密的 下面是加密 EditText 的一个示例 明文文本与之类似
  • 增加录制音频的音量输出

    我正在尝试在 Android 中制作一个通话录音应用程序 我正在使用扬声器录制上行链路和下行链路音频 我面临的唯一问题是音量太低 我已使用 AudioManager 将设备的音量增加到最大值 但不能超过该值 我首先使用MediaRecord
  • 修改使用 from ... import * 导入的模块中的变量

    考虑以下代码 main py From toolsmodule import database foo toolsmodule database mydatabase 看起来 这在每个模块中创建了一个具有不同内容的变量 如何从 main 修
  • 仅 Android 3.x WebView 文本选择 + JavaScript

    问题域 基于 Android WebView 的 ePub 格式阅读器 我们需要可通过 JavaScript 方法访问的文本突出显示 即打开 关闭 保存并通过电子邮件发送等 如果我的理解有误 请知情者指正 在 WebView 上选择文本时
  • Ruby Symbol#to_proc 在 1.9.2-p180 中泄漏引用?

    好的 这是我第二次尝试使用 Sinatra 应用程序调试内存问题 我相信这次我已经将其固定为简单的示例代码 看来当我过滤数组时 map some method 它会导致该数组中的项目无法被垃圾收集 运行等效的 map x x some me