Mögliche Verwendung für SoftReference mit Wertgleichheit

9

Ich komme vorhin zu der Schlussfolgerung, dass, wenn Sie eine SoftReference mit Gleichwertigkeit auf der Grundlage von Wert (Gleichheit) benötigen, ein Entwurf schlecht war, mit Ausnahme eines Interners. Dies folgt Google Collections und Guava ohne eine solche Klasse. Aber ich bin auf ein Problem gestoßen, von dem ich denke, dass es ein solches Objekt verwenden könnte.

Wir haben ein Asset-Management-System in einer Renderfarm für visuelle Effekte mit mehreren hundert Prozessen, die denselben Job ausführen, der sich nur in der von ihm gerenderten Bildnummer unterscheidet. Wir haben eine Oracle-Datenbank, die alle verwendeten Ressourcen aufzeichnen muss. Anstatt Oracle mit identischen Einsätzen zu stampfen, bei denen nur einer von allen Jobs erfolgreich ist, können wir im Asset-Management-System der mittleren Ebene ein HashSet verwenden, um zu protokollieren, ob das Objekt in Oracle eingefügt wird.

Ich könnte einen Google MapMaker mit einem Ablaufdatum verwenden, aber ich möchte nicht befürchten müssen, dass das Ablaufdatum korrekt ist. Wir haben Renderings, die in Stunden und Tagen ausgeführt werden. Die Verwendung einer SoftReference mit Gleichheitsgleichheit klingt nach einem viel besseren Weg, so dass die JVM die Speicherbereinigung automatisch verwaltet.

Für andere Probleme, die ich mit einer ConcurrentHashMap mit Garbage Collection lösen möchte, würde ich eine starke Referenz in der HashMap als Schlüssel verwenden, um equals () Gleichheit und eine SoftReference als Wert zu erhalten, damit die JVM etwas sammeln kann, Aber in diesem Fall spielt der Wert keine Rolle, und ich habe keinen Wert, der in eine SoftReference eingefügt werden soll. So scheint es, als würde die Verwendung einer SoftReference mit equals () den Trick machen.

Irgendwelche anderen Vorschläge dazu?

    
Blair Zajac 12.02.2010, 07:12
quelle

3 Antworten

1

In den meisten Fällen, in denen Sie weiche Referenzen mit Google Collections verwenden möchten, sollten Sie

anrufen %Vor%

Bei starken Schlüsseln, aber weichen Werten, verwenden Nachschlagefunktionen die Gleichheit, und Schlüssel-Wert-Paare werden bei knappem Speicher zu Garbage Collections zusammengefasst.

    
Jared Levy 15.02.2010 06:48
quelle
1

Da es keine ConcurrentHashSet gibt, die weiche Referenzen verwenden, gibt es nur zwei Ansätze:

1.) Ihr Ansatz mit dem ConcurrentHashMap

  • Überschreibe equals und hashCode in SoftReference
  • Innerhalb von equals und hashCode greifen Sie nur auf das Objekt mit SoftReference#get zu
  • Setzen Sie SoftReference als Schlüssel und jedes Objekt als Wert (nur null ist nicht erlaubt)
  • Wenn die Referenz beim Zugriff auf hashCode oder equals veraltet wird, fügen Sie den Verweis zu einer Löschwarteschlange hinzu, um häufig die toten Schlüssel zu entfernen.
  • Auf contains prüfen via containsKey

2.) Verwenden Sie ConcurrentMultimap<Integer, Set<SoftReference<RepLookupEntry>> und verwenden Sie hashCode als Schlüssel und eine synchronisierte Gruppe von SoftReferences als Werte. Wenn Sie einen hashCode Treffer erhalten, prüfen Sie den Inhalt aller SoftReferences auf Gleichheit. Nicht sehr hübsch, stimme ich zu und schwierig zu synchronisieren.

Wenn ich in Ihrer Position wäre, würde ich SoftReferences überhaupt nicht verwenden, sondern eine ConcurrentHashMap, um starke Referenzen zu Ihren POJOs zu behalten. Jedes Mal, wenn ein neues Element eintrifft, legen Sie es auch in eine ConcurrentLinkQueue. Wenn die Warteschlange einen bestimmten Grenzwert überschreitet, beginnen Sie, Elemente aus der HashMap zu entfernen.

    
Christopher Oezbek 23.02.2010 10:25
quelle
0

Ich denke, dass diese Klasse Ihre Bedürfnisse erfüllen wird:

%Vor%

Dies sollte so funktionieren, dass sobald der weiche Verweis, der der Wert ist, gelöscht wird, der Wert nur noch schwach erreichbar ist und der Schlüssel aus der inneren Karte entfernt werden kann.

    
Geoff Reedy 17.02.2010 18:28
quelle