设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2198|回复: 6
打印 上一主题 下一主题

[已经解决] 请问Ruby的GC的原理?

[复制链接]

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

跳转到指定楼层
1
发表于 2014-5-1 15:38:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x

现在有点搞不懂一个对象什么时候会被回收了,于是写了一点代码。下面是Ruby2.0.0中的运行结果

RUBY 代码复制
  1. def test
  2.   GC.start
  3.   arr = []
  4.   100000.times { a_method(arr) }
  5.   p arr.size
  6. end
  7.  
  8. # test1
  9. def a_method(arr)
  10.   obj = 'temp'
  11.   ObjectSpace.define_finalizer(obj, proc {|id| arr.push(id) })
  12. end
  13. test #=> 0
  14.  
  15. # test2
  16. def a_method(arr)
  17.   ObjectSpace.define_finalizer('temp', proc {|id| arr.push(id) })
  18. end
  19. test #=> 69872


在test1中,虽然‘temp’字符串被赋给了变量obj,但是很快obj就出了作用域无法引用了。这个字符串应该是可以被回收的,可是最后却没有被回收。
在test2中,直接把'temp'作为参数传给了define_finalizer,这样倒是可以触发ruby的垃圾回收机制。

所以到底怎么样的对象可以触发ruby的垃圾回收?我以前一直觉得,当一个对象不被任何东西引用的时候就可以被回收了。但是test1证明似乎不是这样?求科普~~

点评

http://ruby-doc.org/core-2.0.0  发表于 2014-5-1 21:23

Lv2.观梦者 (暗夜天使)

梦石
0
星屑
266
在线时间
2355 小时
注册时间
2009-3-13
帖子
2309

贵宾

2
发表于 2014-5-1 18:52:31 | 只看该作者
本帖最后由 Sion 于 2014-5-1 19:01 编辑

貌似那个 define_finalizer 导致无法回收。
RUBY 代码复制
  1. class T
  2. end
  3.  
  4. def m1
  5.   p a = T.new
  6. end
  7.  
  8. m1
  9. GC.start
  10. ObjectSpace.each_object( T ) {|obj| p obj}
  11. puts '已释放 m1中的 T.new'
  12.  
  13. def m2
  14.   p a = T.new
  15.   ObjectSpace.define_finalizer( a, proc {} )
  16. end
  17.  
  18. m2
  19. GC.start
  20. ObjectSpace.each_object( T ) {|obj| p obj}
  21. puts '无法释放 m2 中的 T.new'

运行环境是 1.9.2
这就是 Ruby 饱受诟病的内存泄露吧。其实都是些鸡肋功能...

点评

要看源码吧,这种事还是留给 ruby 开发人员做算咯,用户想点办法绕开它就行了。  发表于 2014-5-1 20:12
这样啊,那顶楼的test2为什么可以回收呢?  发表于 2014-5-1 19:46

评分

参与人数 1星屑 +20 收起 理由
taroxd + 20 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
3 小时
注册时间
2014-5-9
帖子
6
3
发表于 2014-5-13 22:32:35 | 只看该作者
本帖最后由 masix8 于 2014-5-13 22:34 编辑

应该是这样的,定义obj=‘temp’的时候给了一个内存段来存数据,而后面还有使用,这一段是不会当作垃圾的

那个代码里面m2也是,之前定义,后面使用的局部变量不会当作垃圾,全局变量无论何时都不会当作垃圾
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
帖子
1839

开拓者

4
发表于 2014-5-14 00:35:07 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (暗夜天使)

精灵族の天使

梦石
0
星屑
1697
在线时间
3038 小时
注册时间
2007-3-16
帖子
33731

开拓者贵宾

5
发表于 2014-5-14 08:05:32 | 只看该作者
GC只会回收已经不会再引用的东西【也就是断开连接】的东西。
最著名的例子就是
  1. RPG::Cache.clear

  2. Module RPG
  3. Module Cache
  4.   def self.clear
  5. @Cache= {} #清理所有@cache的所有链接
  6.    GC.start #由于失去链接,所有的内存都会被清理
  7.   end
  8. end
  9. end
复制代码

点评

引用次数到零的时候灭掉~  发表于 2014-5-15 06:16
求引用计数的方法。【是不是如果引用的次数达到一定限制就会自动的标记为outdated而强制清除?】  发表于 2014-5-14 21:28
这个基本方法就叫做标记扫除。。还有一种方法叫引用计数。。常见的高级GC策略都是这两个组合来的  发表于 2014-5-14 21:15
我本来就是这么理解的  发表于 2014-5-14 18:40
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
帖子
1839

开拓者

6
发表于 2014-5-14 21:09:58 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
帖子
1839

开拓者

7
发表于 2014-5-14 23:10:36 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-9-25 13:20

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表