2010-03-08 24 views
10

¿Hay alguna forma de rubí para obtener la dirección de memoria de los objetos ..Accediendo a la dirección de memoria de objetos en ruby ​​...?

dicen ..

(i = 5) que es posible obtener la dirección de ese objeto mem .. 5

que han estado tratando de conseguir esto durante algún tiempo ..,

Cualquier respuesta sería muy apreciada ...

gracias,

Recuerdos levirg

+10

¿Por qué? ¿Que estás tratando de hacer? – SLaks

Respuesta

3

No conozco la forma de tener la dirección exacta, pero ¿quizás estás buscando algo como el método object_id?

extracto de sus documentation

devuelve un identificador de número entero para obj.
El mismo número será devuelto en todas las llamadas a ID para un objeto dado, y no hay dos objetos activos compartirá un id


Ejemplo:

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

Ruby Memory Validator debe ser capaz para llevarlo a cabo, pero no es gratis.

Aman Gupta patched Joe Damatos memprof pero parece que hay una work in progress y nunca me dieron para que se ejecute en mi máquina. Joe tiene un par de publicaciones realmente buenas sobre memprof y otras cosas de bajo nivel en su blog.

Ahora no estoy tan seguro de que realmente puedan hacerlo. Los enteros se almacenan como Fixnum y Fixnum no es un objeto Ruby habitual, simplemente se ve de esa manera. Ruby usa un ingenioso truco de aceleración con el object_id para hacer que Fixnum modifique los valores de los objetos. El número se almacena en el propio object_id. Es por eso que dos Fixnum diferentes que contienen el mismo valor tienen el mismo object_id.

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

El object_id de un Fixnum es en realidad creado por desplazamiento de bits a la izquierda, y luego poner el bit menos significativo.

5 es 0b101 y la object_id para 5 es 11 y 11 en binario es 0b1011.

4711 es 0b0001001001100111, desviación a la izquierda así como el bit y se obtiene 0b0010010011001111 y que es 9423, que pasa a ser el object_id para z anteriormente.

This behaviour es muy probablemente una implementación específica, pero no sé de una implementación de Ruby que no maneje Fixnum de esta manera.

Hay al menos otros tres objetos más en Ruby y eso es false, true y nil.

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

parece que memprof es bueno para 64 bits, el mío es 32 bits ..... gracias – levirg

+0

Gracias, me perdí eso en el léame para memprof. También estoy en 32 bits. Vea arriba para una explicación de cómo Ruby almacena Fixnum. –

+0

que fue genial, he aprendido algo de eso ... gracias hombre ... – levirg

0

¿Qué estás tratando de hacer exactamente?

Tenga en cuenta que un objeto Ruby no es directamente análoga a una variable en un lenguaje como C o C++. Por ejemplo:

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 

Incluso a través de a y b son variables independientes, que son referencias a los mismos datos subyacentes y tienen el mismo object_id.

Si ves que necesitas para tomar la dirección de una variable, es probable que un enfoque más fácil de lo que usted está tratando de hacer.

+0

Solo quería saber cómo hacer referencia a los objetos para trabajar en ruby, así que pensé que la dirección sería útil, para hacer las cosas ... si hay alguna manera mejor de ayudarme por favor ... gracias – levirg

+0

No debería tener que preocuparse por hacer referencia a un objeto en Ruby. A diferencia de otros idiomas en los que puede pasar un objeto por valor o por referencia, Ruby maneja todos los aspectos de bajo nivel por usted. Todo lo que debe hacer es usar el objeto y pasarlo como lo haría si estuviera pasando por valor en C. Para obtener más información acerca de las partes internas de Ruby, consulte http://www.ruby-doc.org/docs/. ProgrammingRuby/language.html. – bta

1

Ruby Memory Validator le otorga la dirección de memoria para el objeto.

trabajo de Joe Damato (http://timetobleed.com/plugging-ruby-memory-leaks-heapstack-dump-patches-to-help-take-out-the-trash) y (http://timetobleed.com/memprof-a-ruby-level-memory-profiler) se basa en el trabajo de software de verificación hizo para crear una API de inspección de la memoria de Ruby (http://www.softwareverify.com/ruby/customBuild/index.html).

Joe lo describe en su blog. Por lo tanto, el trabajo de Joe también debería devolver las direcciones apropiadas. No estoy al día con la última versión del trabajo de Joe, él solo me habló de la primera versión, no de la última, pero si sigue las asignaciones de memoria en las bases de Ruby, está rastreando las direcciones de los objetos que contienen lo que sea que estás asignando.

Eso no significa que pueda eliminar la referencia de la dirección y leer el valor de los datos se puede esperar encontrar en esa dirección. La desreferenciación de la dirección lo dirigirá a las partes internas de un objeto Ruby básico. Los objetos de Ruby son un objeto básico que almacena datos adicionales junto con ellos, por lo que conocer la dirección real no es muy útil a menos que estés escribiendo una herramienta como Ruby Memory Validator o memprof.

¿Cómo sé lo anterior sobre Ruby memoria Validador y la API liberamos? Diseñé Ruby Memory Validator. También escribí los bits del lenguaje ensamblador que interceptan las llamadas de Ruby que asignan la memoria.

0

Desde que se indica (enterrado en un comentario en algún lugar) que en realidad está tratando de entender cómo Rubí hace referencia a las cosas, creo que las cosas funcionan de la siguiente manera:

Un VALUE en la API C de Ruby representa un objeto (una nil, FixNum o Boolean) o un puntero a Object. El VALUE contiene una etiqueta de 3 bits que indica cuál de ellos es y contiene el valor (para los primeros 3) o un puntero de memoria directa (para un Object). No hay forma de llegar a la VALUE directamente en Ruby, (no estoy seguro de si el object_id es el mismo o diferente.)

Tenga en cuenta que JRuby funciona de forma diferente.

9

Sí.

De "Fiddling with Ruby’s Fiddle":.

"Usted puede obtener el valor del puntero real de un objeto tomando el identificador de objeto, y haciendo un cambio de bit a bit hacia la izquierda Esto le dará el puntero (o la memoria ubicación) del objeto ruby ​​en la memoria ".

Usando su ejemplo de i = 5 se podría hacer de esta manera:

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?" tiene más información sobre object_id, incluyendo una breve introducción a la fuente de C se basa la aplicación que pueden ser útiles .

Eche un vistazo a "Fiddle" para conocer otras cosas interesantes que puede hacer.

+0

No estoy seguro de por qué esta respuesta no se votó más, ¡esto ayuda muchísimo! Si tiene 'foo = Class.new' then' foo.to_s' devuelve algo así como "# ". Al mirar el código fuente de Ruby, esta cadena se asigna a @tmp_classpath. Sin embargo, una vez que asigna este objeto a una constante, 'Foo = foo',' foo.to_s' devuelve "Foo" y se elimina @tmp_classpath. Tengo mensajes de depuración tanto antes como después de la asignación constante, y ahora puedo usar '(foo.object_id << 1) .to_s (16)' para emparejarlos. – fastryan

Cuestiones relacionadas