¿Es seguro tener un PhantomReference a `this`?

Marcono1234:

Tengo un recurso compartido para el que me gustaría saber cuántos otros objetos siguen utilizando este recurso. Para ello me gustaría usar PhantomReferences.

Dado que ReferenceQueues no mantienen un registro de las referencias registradas para ellos ( fuente , la sección "Notificación"), mi idea era almacenar la referencia como campo del objeto a seguir:

class Foo {
    private PhantomReference<Foo> thisReference;

    public Foo(ReferenceQueue<Foo> queue) {
        thisReference = new PhantomReference<>(this, queue);
    }
}

Es esto seguro, basado en Java 9 comportamiento (+) de PhantomReferences, o es posible que una instancia se recoge la basura sin la referencia que se añade a la cola?

La documentación dice:

Supongamos que el recolector de basura determina en un cierto punto en el tiempo que un objeto es alcanzable fantasma. En ese momento se atómicamente borrar todas las referencias a ese objeto fantasma y todas las referencias a cualquier otro fantasma objetos fantasmas alcanzable desde la que ese objeto es accesible. Al mismo tiempo o en algún momento posterior se ponga en cola esas referencias fantasma limpiado recientemente que están registrados con colas de referencia.

Pero no menciona si la recolección de basura puede ocurrir antes de que se encolan las referencias.

Holger:

El paquete de documentación contiene la frase engañosa: “Un objeto es fantasma puede llegar si no es ni con fuerza, suavidad, ni débilmente accesible, se ha finalizado, y alguna referencia fantasma se refiere a ella.”

Que “alguna referencia fantasma” no hace hincapié en el hecho de que el propio objeto de referencia debe ser alcanzable, que se indica en la notificación de la sección:

La relación entre un objeto de referencia registrada y su cola es unilateral. Es decir, una cola no hace un seguimiento de las referencias que están registrados con ella. Si una referencia registrada en sí se vuelve inalcanzable, entonces nunca se pone en cola.

Ya que al ser alcanzable fantasma no tiene consecuencias prácticas, aparte de causar potencialmente la enqueuing de referencias fantasma, esto es todo lo que importa.

Tenga en cuenta que las definiciones de asequibilidad suaves y débiles son mejores:

  • Un objeto es suavemente alcanzable si no es fuertemente accesible pero puede ser alcanzado por la que atraviesa una referencia suave.
  • Un objeto es débilmente alcanzable si no es ni fuerte ni en voz baja alcanzable, pero se puede llegar atravesando una referencia débil. ...

A continuación, se hace hincapié en que el objeto debe ser accesible a través de los objetos de referencia, lo que implica que los objetos de referencia debe ser accesible también.

El problema con la definición de alcanzabilidad fantasma de una manera similar, es decir, que los fantasmas objetos alcanzables son en realidad inalcanzable, ya que las PhantomReferencemodificaciones de la get()método para siempre vuelven null, por lo que una aplicación no puede alcanzar el referente y por lo tanto, no atravesar objetos alcanzables fantasma.

Tal vez, una mejor definición habría sido

  • Un objeto es fantasma puede llegar si no es ni con fuerza, suavidad, ni débilmente accesible, se ha finalizado, pero se puede llegar por el recolector de basura por la que atraviesa una referencia fantasma.

Con esa definición, sería bastante claro que su ejemplo con una autorreferencia no funcionaría, al igual que lo sería no funcionar con una WeakReferenceo SoftReference. Tenga en cuenta que cuando la clase no tiene dedicada finalize()método, no hay ninguna diferencia práctica entre usar una WeakReferenceo una PhantomReference.

Parece que incluso los diseñadores de la API no entendían las implicaciones completamente, ya que la especificación de Java antes de la 9 contenía la regla:

A diferencia de las referencias blandos y débiles, las referencias fantasma no se borran automáticamente por el recolector de basura, ya que están en cola. Un objeto que es accesible a través de referencias fantasma permanecerá así hasta que todas estas referencias se borran o ellos mismos se convierten en inalcanzables.

lo que evidentemente ignora el punto de que una puede llegar fantasma objeto no es accesible, al menos desde un punto de vista de aplicación y mantenerlo Phantom accesible a la vista de un recolector de basura no tiene ningún beneficio práctico. No hacer el objeto vivo de nuevo, es la misma diferencia de su finalización. Pero tenga en cuenta que en este lugar, la documentación reconoció que si una misma referencia fantasma se vuelve inalcanzable, el referente deja de ser accesible fantasma .

A partir de Java 9, las referencias fantasma se borran automáticamente cuando en cola, por lo que la implicación sólo prácticos de la transición de un objeto a partir fantasma puede llegar a inalcanzable , es la referencia fantasma está en cola. Que requiere que el objeto de referencia para ser alcanzable.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=201966&siteId=1
Recomendado
Clasificación