Wenn Sie Plug-in-Evictor (Bereinigungsprogramme) verwenden, werden diese erst aktiv, nachdem Sie sie erstellt und einer BackingMap zugeordnet haben. Mit Hilfe der folgenden bewährten Verfahren können Sie die Leistung für LFU- und LRU-Evictor erhöhen.
Das Konzept von LFU-Evictor (Bereinigungsprogramm) sieht vor, dass Einträge aus der Map entfernt werden, die nur selten verwendet werden. Die Einträge der Map sind auf eine festgelegte Menge binärer Heapspeicher verteilt. Je öfter ein bestimmter Cacheeintrag verwendet wird, desto höher wird er im Heapspeicher eingereiht. Wenn der Evictor versucht, Bereinigungen durchzuführen, entfernt er nur die Cacheeinträge, die sich unterhalb eines bestimmten Punkts des binären Heapspeichers befinden. Deshalb werden nur die so genannten LFU-Einträge (Last Frequently Used, am wenigsten verwendet) Einträge bereinigt.
Der LRU-Evictor (Bereinigungsprogramm) folgt bis auf wenige Unterschiede denselben Konzepten wie der LFU-Evictor. Der Hauptunterschied besteht darin, dass der LRU-Evictor eine First In/First Out-Warteschlange (FIFO) an Stelle einer Gruppe binärer Heapspeicher verwendet. Jedesmal, wenn auf einen Cacheeintrag zugegriffen wird, wird dieser an den Anfang der Warteschlange gestellt. Deshalb stehen oben in der Warteschlange die am häufigsten verwendeten Map-Eintrag und unten in der Warteschlange die am wenigsten verwendeten Map-Einträge. Beispiel: Der Cacheeintrag A wird 50 Mal verwendet, und der Cacheeintrag B wird nur ein einziges Mal direkt nach Cacheeintrag A verwendet. In dieser Situation steht der Cacheeintrag B am Anfang der Warteschlange, weil er zuletzt verwendet wurde, und der Cacheeintrag A steht am Ende der Warteschlange. Der LRU-Evictor entfernt die Cacheeinträge, die sich hinten in der Warteschlange befinden, weil es sich hierbei um die LRU-Map-Einträge (Least Recently Used) handelt, d. h., deren Verwendungszeit am ältesten ist.
Wenn Sie den LFU-Evictor verwenden, werden alle Cacheeinträge für eine bestimmte Map über die von Ihnen angegebene Anzahl von Heapspeichern sortiert, was die Leistung erheblich verbessert und verhindert, dass alle Bereinigungsoperationen in einem einzigen binären Heapspeicher synchronisiert werden müssen, der die gesamte Sortierung für die Map enthält. Eine höhere Anzahl an Heapspeichern verringert auch die erforderliche Zeit für die Neusortierung der Heapspeicher, weil jeder Heapspeicher weniger Einträge enthält. Setzen Sie die Anzahl der Heapspeicher auf 10 % der Eintragsanzahl in Ihrer BaseMap.
Wenn Sie den LRU-Evictor verwenden, werden alle Cacheeinträge für eine bestimmte Map über die von Ihnen angegebene Anzahl von LRU-Warteschlangen sortiert, was die Leistung erheblich verbessert und verhindert, dass alle Bereinigungsoperationen in einer einzigen Warteschlange synchronisiert werden müssen, die die gesamte Sortierung für die Map enthält. Setzen Sie die Anzahl der Warteschlangen auf 10 % der Eintragsanzahl in Ihrer BaseMap.
Wenn ein LFU- oder LRU-Evictor mit dem Entfernen von Einträgen beginnt, verwendet er die Evictor-Eigenschaft "MaxSize", um festzustellen, wie viele binäre Heapspeicher bzw. LRU-Warteschlangenelemente bereinigt werden müssen. Angenommen, Sie legen die Anzahl der Heapspeicher bzw. Warteschlangen so fest, dass je Map-Warteschlange ungefähr 10 Map-Einträge enthält. Wenn die Eigenschaft "MaxSize" auf 7 gesetzt ist, entfernt der Evictor 3 Einträge aus jedem Heapspeicher bzw. Warteschlangenobjekt, um die Größe der einzelnen Heapspeicher bzw. Warteschlangen wieder auf 7 zurückzusetzen. Der Evictor entfernt nur dann Map-Einträge aus einem Heapspeicher bzw. aus einer Warteschlange, wenn die Anzahl der im Heapspeicher bzw. in der Warteschlange enthaltenen Elemente höher ist als der Wert der Eigenschaft "MaxSize". Setzen Sie die Eigenschaft "MaxSize" auf 70 % Ihrer Heapspeicher- bzw. Warteschlangengröße. In diesem Beispiel wird die Eigenschaft auf 7 gesetzt. Sie können die ungefähre Größe jedes Heapspeichers bzw. jeder Warteschlange bestimmen, indem Sie die Anzahl der BaseMap-Einträge durch die Anzahl der verwendeten Heapspeicher bzw. Warteschlangen teilen.
Ein Evictor entfernt nicht ständig Einträge aus der Map. Vielmehr ist es eine gewisse Zeit inaktiv und prüft die Map nur alle n Sekunden, wobei n für den Wert der Eigenschaft "SleepTime" steht. Diese Eigenschaft wirkt sich auch positiv auf die Leistung aus. Wird die Bereinigung zu häufig durchgeführt, verringert sich die Leistung, weil Ressourcen für die Bereinigung benötigt werden. Wird der Evictor zu selten ausgeführt, können sich Einträge in einer Map ansammeln, die eigentlich nicht benötigt werden. Eine Map, die sehr viele nicht benötigte Einträge enthält, kann sich nachteilig auf den Speicherbedarf und auf die Verarbeitungsressourcen auswählen, die für Ihre Map erforderlich sind. Für die meisten Maps empfiehlt es sich, das Bereinigungsintervall auf 15 Sekunden zu setzen. Wenn eine Map viele Schreiboperationen und eine hohe Transaktionsrate aufweist, sollten Sie das Intervall verringern. Wird nur selten auf die Map zugegriffen, können Sie einen höheren Wert festlegen.
Der Beispielcode definiert eine Map definiert, erstellt einen neuen LFU-Evictor, setzt die Eigenschaften für den Evictor und stellt die Map so ein, dass der Evictor verwendet wird:
// ObjectGridManager zum Erstellen/Abrufen des ObjectGrids verwenden (siehe den
// Abschnitt zu ObjectGridManger)
ObjectGrid objGrid = ObjectGridManager.create............
BackingMap bMap = objGrid.defineMap("SomeMap");
// Eigenschaften, ausgehend von 50.000 Map-Einträgen, definieren
LFUEvictor someEvictor = new LFUEvictor();
someEvictor.setNumberOfHeaps(5000);
someEvictor.setMaxSize(7);
someEvictor.setSleepTime(15);
bMap.setEvictor(someEvictor);
Die Verwendung des LRU-Evictors ist der Verwendung eines LFU-Evictors sehr ähnlich. Es folgt ein Beispiel:
ObjectGrid objGrid = new ObjectGrid;
BackingMap bMap = objGrid.defineMap("SomeMap");
// Eigenschaften, ausgehend von 50.000 Map-Einträgen, definieren
LRUEvictor someEvictor = new LRUEvictor();
someEvictor.setNumberOfLRUQueues(5000);
someEvictor.setMaxSize(7);
someEvictor.setSleepTime(15);
bMap.setEvictor(someEvictor);
Beachten Sie, dass sich nur zwei Zeilen vom Beispiel für den LFU-Evictor unterscheiden.