2010-03-08 51 views
10

是否有红宝石任何方式来获得对象的内存地址..在ruby中访问对象的内存地址?

说..

(I = 5)是可能获得该对象5的MEM地址..

我一直在尝试过一段时间才能得到这个..,

任何答案将非常感激......

感谢,

Regards levirg

+10

为什么?你想做什么? – SLaks 2010-03-08 15:13:43

回答

3

我不知道有确切的地址,但也许你正在寻找像object_id方法的东西?从其documentation

提取物返回物镜的整数标识符。
同样的号码将所有呼叫返回到ID为给定的对象,并没有两个活动对象将共享一个ID


例子:

> 5.object_id 
=> 11 
> true.object_id 
=> 2 
7

Ruby Memory Validator应该能够把它拉开,但它不是免费的。

Aman Gupta patched Joe Damatos​​但它似乎是 work in progress,我从来没有在我的机器上运行它。 Joe在他的 blog上有一些关于memprof和其他低级别内容的非常好的帖子。

现在我不太确定他们真的可以。整数存储为Fixnum,而Fixnum不是通常的Ruby对象,它只是看起来这样。 Ruby使用巧妙的加速技巧与object_id来使Fixnum对象具有immidiate值。该号码实际上存储在object_id本身中。这就是为什么包含相同值的两个不同的Fixnum具有相同的object_id

>> x=5 
=> 5 
>> y=5 
=> 5 
>> x.object_id 
=> 11 
>> y.object_id 
=> 11 
>> z=4711 
=> 4711 
>> z.object_id 
=> 9423 

一个Fixnumobject_id实际上是由比特移位到左边,然后设置至少显著位创建。

50b101object_id5是二进制11110b1011是。

47110b0001001001100111,左移并设置位,你会得到0b0010010011001111那就是9423这恰好是object_id以上z

This behaviour最有可能是实现特定的,但我不知道这样处理Fixnum的Ruby实现。

Ruby中至少有三个直接对象,即false,truenil

>> false.object_id 
=> 0 
>> true.object_id 
=> 2 
>> nil.object_id 
=> 4 
+0

它似乎memprof工作良好的64位,我的是32位.....谢谢 – levirg 2010-03-09 05:00:41

+0

谢谢,我错过了memprof的自述。我也在32位。有关Ruby如何存储Fixnum的说明,请参阅上文。 – 2010-03-09 08:30:48

+0

这是伟大的,我已经从中学到了一些东西...谢谢你.. – levirg 2010-03-09 09:04:14

0

你究竟想要做什么?

请记住,Ruby对象不是直接类似于C或C++语言中的变量。例如:

a = "foo" 
b = a 
b[2] = 'b' 
b 
    => "fob" 
a 
    => "fob" 
a == b 
    => true 
a.object_id 
    => 23924940 
b.object_id 
    => 23924940 
a.object_id == b.object_id 
    => true 

即使通过ab是分开的变量,它们是相同的底层数据的引用,并且具有相同object_id

如果您发现自己需要获取变量的地址,那么无论您想要做什么,都可能有一个更简单的方法。

+0

我只是想知道如何引用对象工作的红宝石,所以我认为地址将是有用的,要完成的事情.....如果有更好的方式请帮助我...谢谢 – levirg 2010-03-09 05:31:37

+0

你不应该担心在Ruby中引用一个对象。与其他语言相比,您可以通过值或引用传递对象,Ruby将为您处理所有低级别方面。所有你需要做的就是使用这个对象,并且像在C中传递值一样传递它。有关Ruby内部的更多信息,请参见http://www.ruby-doc.org/docs/ ProgrammingRuby/language.html。 – bta 2010-03-09 22:11:39

1

Ruby Memory Validator确实为您提供了该对象的内存地址。

Joe Damato的作品(http://timetobleed.com/plugging-ruby-memory-leaks-heapstack-dump-patches-to-help-take-out-the-trash)和(http://timetobleed.com/memprof-a-ruby-level-memory-profiler)基于软件验证为创建Ruby内存检查API(http://www.softwareverify.com/ruby/customBuild/index.html)所做的工作。

乔在他的博客中描述过。因此乔的工作也应该返回适​​当的地址。我并未完全了解最新版本的Joe的工作 - 他只告诉我有关第一个版本,而不是最新版本,但是,如果您在Ruby的基础上跟踪内存分配,那么您正在跟踪地址无论你正在分配什么东西。

这并不意味着您可以取消引用地址并读取您希望在该地址找到的数据值。解引用地址将指向基本Ruby对象的内部。 Ruby对象是一个基本对象,然后将附加数据存储在一起,因此,除非您正在编写像Ruby Memory Validator或memprof这样的工具,否则了解实际地址并不是非常有用。

我如何知道上面关于Ruby Memory Validator和我们发布的API?我设计了Ruby Memory Validator。我还编写了拦截分配内存的Ruby调用的汇编语言位。

0

你既然标明(埋在评论的地方),你真的只是想了解Ruby的是如何引用的东西,我想工作的事情如下:

在Ruby的C API一个VALUE代表对象(一nilFixNumBoolean)或指向Object的指针。 VALUE包含一个3位标记,指示它们是哪一个,并且包含值(对于前3个)或直接存储器指针(对于Object)。在Ruby中无法直接获取VALUE(我不确定object_id是相同还是不同)。

请注意,JRuby的运行方式不同。

9

是的。

从“Fiddling with Ruby’s Fiddle”:

“你可以通过拍摄物体的ID,做一个按位左移得到一个对象的实际指针值这会给你的指针(或内存位置)的红宝石对象在内存中。“

使用您的i = 5例如它可以做像这样:

i = 5 
i_ptr_int = i.object_id << 1 
=> 22 

In Ruby, why does inspect() print out some kind of object id which is different from what object_id() gives?”有更多的信息关于object_id,包括简要介绍了C源代码,你可能会发现有用的执行标的。

看看“Fiddle”,你可以做一些其他很酷的事情。

+0

不知道为什么这个答案不是更多投票,这有助于巨大!如果你有'foo = Class.new',那么'foo.to_s'返回类似于“#”的东西。查看Ruby源代码,该字符串被分配给@tmp_classpath。但是,一旦将此对象分配给常量,“Foo = foo”,“foo.to_s”将返回“Foo”,并且将移除@tmp_classpath。我在常量赋值之前和之后都有调试消息,现在可以使用'(foo.object_id << 1).to_s(16)'将它们配对。 – fastryan 2016-02-17 19:56:30