[pyar] La función id y acceso a objetos en la memoria

Alejandro Santos listas en alejolp.com
Sab Ene 3 23:12:03 ART 2015


2015-01-04 0:01 GMT+01:00 fisa <fisadev en gmail.com>:
>
> Pero por ahí hay algún detalle extra de implementación, que haga que se
> termine leyendo el objeto. O que sea necesario porque no compara posiciones
> de memoria sino algún otro tipo de metadato escondido en el objeto en sí
> (qué se yo, por ahí lleva un id propio de cpython por algún motivo oscuro
> del compilador).
>

Como ya te mostró Lucio, en Python, id() devuelve un cast del puntero
PyObject* como Long. Pero en Java con la JVM de Sun/Oracle hace
exactamente esto.

> No hay un problema concreto, solo estaba pensando cómo lo haría yo, y ahora
> quiero saber cómo sucede en cpython.
>

¿Cómo lo harías vos?

El GC no mueve objetos en memoria, sino que una vez que tenés una
instancia el objeto siempre mantiene su misma posición de memoria.
Otros lengajes como Java con la JVM de Sun, .Net, y OCaml si lo hacen;
el GC después de liberar suficiente memoria reacomoda los objetos en
memoria para reducir la fragmentación y mejorar el uso de la memoria.

En Python esto tiene el efecto que en aplicaciones de larga duración
tenés fragmentación interna de memoria, y tu aplicación puede usar el
doble de memoria que la realmente usada. Las primeras versiones de
Firefox cuando los usabas por unas horas usaban un montón de memoria,
justamente por esto. Claudio Freire dio una presentación de esto hace
unos años en PyConAr.

En el caso de Java, el id() de un objeto no te devuelve el puntero
sino que te devuelve un número almacenado en el header del objeto que
no necesariamente tiene que ver con el puntero, porque el GC puede
mover el objeto en memoria y el puntero dejaría de ser válido. Creo
que no se puede desde código Java averiguar el id(), lo más parecido
es System.identityHashCode() que la JVM lo implementa con el puntero.

La forma más fácil de implementar esto es teniendo una tabla
intermedia. Cuando tenés una variable con una referencia a un objeto,
inicializás la variable con el código de la tabla, de forma que cuando
el GC mueve el objeto en memoria el único puntero que tenés que
actualizar es el de esta tabla. Ni idea si Java lo hace de esta forma.

-- 
Alejandro Santos


More information about the pyar mailing list