Se WeakHashMap cada vez mayor, o lo hace a despejar las claves de basura?

Albahaca Bourque:

Estoy tratando de utilizar WeakHashMapcomo un concurrente Setde referencias débiles.

    this.subscribers =
            Collections.synchronizedSet(
                    Collections.newSetFromMap(
                            new WeakHashMap <>()
                    )
            );

Cuando un elemento se va a recolección de basura, mi juego continúa informando que como parte de la colección. Por lo tanto, parece que el mapa se cada vez mayor.

La documentación dice:

Cuando una tecla se ha descartado su entrada se elimina de manera efectiva desde el mapa, ...

Pero eso no parece ser el caso en la práctica.

¿Hay siempre un punto en el que los WeakHashMapborra los restos?

Albahaca Bourque:

Sí, llaves borran después de la basura se recoge en realidad

Sí, WeakHashMapno limpiar el detritus. Las claves que han ido a la recolección de basura ya no se informaron en el tamaño. Pero hay que esperar a recolección de basura realice de verdad.

Parece probable que usted era incorrecta sobre los objetos que van a recolección de basura. Tal vez sus objetos se convirtieron en candidatos para la recolección de basura, pero que aún no han sido recogidos. Trate de invocar el recolector de basura y esperar un momento para que se complete. Pero recuerde, la llamada a System.gc()es sólo una sugerencia a la JVM y puede ser ignorada dependiendo de la implementación JVM y escenario de tiempo de ejecución actual.

Aquí es una aplicación de ejemplo completo. Tenga en cuenta que la Setinforma de una disminución de sizesi llamar Set::removeo dejar que el objeto salga del ámbito.

package com.basilbourque.example;

import java.util.Collections;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;

public class WeakHashMapExercise {

    public static void main ( String[] args ) {
        WeakHashMapExercise app = new WeakHashMapExercise();
        app.doIt();
    }

    private void doIt ( ) {
        Set < UUID > set =
                Collections.synchronizedSet(
                        Collections.newSetFromMap(
                                new WeakHashMap <>()
                        )
                );

        UUID uuid1 = UUID.fromString( "a8ee1e34-cead-11e8-a8d5-f2801f1b9fd1" );
        UUID uuid2 = UUID.fromString( "39bda2b4-5885-4f56-a900-411a49beebac" );
        UUID uuid3 = UUID.fromString( "0b630385-0452-4b96-9238-20cdce37cf55" );
        UUID uuid4 = UUID.fromString( "98d2bacf-3f7f-4ea0-9c17-c91f6702322c" );

        System.out.println( "Size before adding: " + set.size() );

        set.add( uuid1 );
        set.add( uuid2 );
        set.add( uuid3 );
        set.add( uuid4 );

        System.out.println( "Size after adding 4 items: " + set.size() );  // Expect 4.

        set.remove( uuid3 );

        System.out.println( "Size after removing item # 3: " + set.size() );  // Expect 3.

        uuid2 = null;  // Release that UUID to garbage-collection.

        // That released object may still appear in our `Set` until garbage collection actually executes. 
        System.gc(); // Ask the JVM to run the garbage-collection. Only a suggestion, may be ignored.
        try {
            Thread.sleep( 1_000 );  // Wait a moment, just for the heck of it.
        } catch ( InterruptedException e ) {
            e.printStackTrace();
        }

        System.out.println( "Size after making garbage of item # 2: " + set.size() );  // Expect 2.

        for ( UUID uuid : set ) {
            System.out.println( uuid.toString() );
        }


    }
}

Ver este código ejecutar en vivo en IdeOne.com .

Talla antes de añadir: 0

Tamaño después de la adición de 4 artículos: 4

Tamaño después de retirar el artículo # 3: 3

Tamaño después de hacer la basura del artículo # 2: 2

En mi caso, el uso de Java 10.0.2 versión de OpenJDK basadas en Zulu JVM de Azul Systems , el recolector de basura parece estar activando bajo mi petición. Si comento hacia fuera el retraso de un segundo, o la System.gcllamada, entonces el último tamaño informó restos 3en lugar de la esperada 2.

Incluso se puede ver este comportamiento cuando se ejecuta este código en vivo en IdeOne.com . Observe cómo el último artículo es 3, pero arriba es 2.

Talla antes de añadir: 0

Tamaño después de la adición de 4 artículos: 4

Tamaño después de retirar el artículo # 3: 3

Tamaño después de hacer la basura del artículo # 2: 3

Supongo que te gusta

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