Есть ли любой путь в рубине для получения адреса памяти объектов..
сказать..
(я = 5), настолько возможно получить адрес мадам того объекта 5..
Я пытался получить это за некоторое время..,
Любой ответ действительно ценился бы...
спасибо,
Отношения levirg
Ruby Memory Validator должен быть в состоянии сделать это, но он не бесплатный.
Aman Gupta patched Joe Damatos memprof, но, похоже, это work in progress, и я так и не смог запустить его на своей машине. У Джо есть пара действительно хороших статей о memprof и других низкоуровневых вещах в его блоге.
Теперь я не уверен, что они действительно могут. Целочисленные числа хранятся как Fixnum
, а Fixnum
- это не обычный объект Ruby, он просто так выглядит. Ruby использует хитрый трюк ускорения с object_id
, чтобы сделать объекты Fixnum
неподвижными значениями. На самом деле номер хранится в самом 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
object_id
в Fixnum
фактически создается путем сдвига битов влево и установки наименее значимого бита.
5
это 0b101
и object_id
для 5
это 11
и 11
в двоичном виде это 0b1011
.
4711
- это 0b0001001001100111
, сдвиньте влево и установите бит, и вы получите 0b0010010011001111
, а это 9423, который оказывается object_id
для z
выше.
Такое поведение, скорее всего, зависит от реализации, но я не знаю ни одной реализации Ruby, которая бы не обрабатывала Fixnum таким образом.
В Ruby есть по крайней мере еще три непосредственных объекта, и это false
, true
и nil
.
>> false.object_id
=> 0
>> true.object_id
=> 2
>> nil.object_id
=> 4
Что именно вы пытаетесь сделать?
Помните, что 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
Даже через a
и b
являются отдельными переменными, они являются ссылками на одни и те же базовые данные и имеют одинаковый object_id
.
Если вам нужно получить адрес переменной, вероятно, есть более простой подход к тому, что вы пытаетесь сделать.
Я не знаю, как узнать точный адрес, но, может быть, вы ищете что-то вроде метода object_id
?
Выдержка из документации
Возвращает целочисленный идентификатор для obj.
Один и тот же номер будет возвращен при всех вызовах идентификатора для данного объекта, и никакие два активных объекта не будут иметь общий идентификатор
Пример:
> 5.object_id
=> 11
> true.object_id
=> 2
Ruby Memory Validator действительно дает вам адрес памяти для объекта.
Работа Джо Дамато (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) основана на работе Software Verification по созданию API проверки памяти Ruby (http://www.softwareverify.com/ruby/customBuild/index.html).
Джо описывает это в своем блоге. Поэтому работа Джо также должна вернуть соответствующие адреса. Я не совсем в курсе последней версии работы Джо - он рассказал мне только о первой версии, а не о последней, но, тем не менее, если вы отслеживаете выделение памяти в основах Ruby, вы отслеживаете адреса объектов, которые хранят то, что вы выделяете.
Это не означает, что вы можете разыменовать адрес и прочитать значение данных, которое вы ожидаете найти по этому адресу. Разыменование адреса укажет вам на внутреннюю часть базового объекта Ruby. Объекты Ruby - это базовый объект, который затем хранит дополнительные данные, поэтому знание фактического адреса не очень полезно, если только вы не пишете инструмент вроде Ruby Memory Validator или memprof.
Откуда я знаю все вышесказанное о Ruby Memory Validator и выпущенном нами API? Я разработал Ruby Memory Validator. Я также написал биты на языке ассемблера, которые перехватывают вызовы Ruby, выделяющие память.
Поскольку вы указали (похоронены в комментарий где-то), что вы на самом деле просто пытаетесь понять, как Ruby ссылается на вещи, я думаю, что все работает следующим образом:
A VALUE
в Ruby C api представляет объект (a nil
, FixNum
или Boolean
) или указатель на объект
. VALUE
содержит 3-битный тег, указывающий, какой из них является, и содержит значение (для первых 3) или прямой указатель памяти (для объекта
). Невозможно получить VALUE
непосредственно в Ruby (я не уверен, тот же или другой object_id
).
Обратите внимание, что JRuby работает по-другому.