DelayQueue mit höherer Geschwindigkeit remove ()?

9

Ich habe ein Projekt, das die Zustandsinformationen in über 500.000 Objekten verfolgt, das Programm empfängt 10.000 Aktualisierungen / Sekunde über diese Objekte, die Aktualisierungen bestehen aus neuen, Aktualisierungs- oder Löschoperationen.

Im Rahmen des Programms müssen etwa alle fünf Minuten Hausaufgaben an diesen Objekten durchgeführt werden. Zu diesem Zweck habe ich sie in DelayQueue eingefügt, um die Delayed -Schnittstelle zu implementieren, was die Sperrfunktion von DelayQueue ermöglicht. um das Haushalten dieser Objekte zu kontrollieren.

  • Neu wird ein Objekt auf dem DelayQueue platziert.

  • Beim Aktualisieren wird das Objekt remove() 'd von DelayQueue aktualisiert und dann an der neuen Position, die von den aktualisierten Informationen bestimmt wird, erneut eingefügt.

  • Nach dem Löschen ist das Objekt remove() 'd von DelayQueue .

Das Problem, mit dem ich konfrontiert bin, ist, dass die remove() -Methode zu einer prohibitiv langen Operation wird, sobald die Warteschlange etwa 450.000 Objekte passiert.

Das Programm ist Multithread, ein Thread kümmert sich um Updates und ein anderer um die Hausverwaltung. Aufgrund der Verzögerung remove() erhalten wir fiese Probleme mit der Sperrleistung, und schließlich verbraucht der Update-Thread-Puffer den gesamten Heap-Speicher.

Ich habe es geschafft, dies zu umgehen, indem ich eine DelayedWeakReference (extends WeakReference implements Delayed) erstelle, die es mir erlaubt, "Schatten" -Objekte in der Warteschlange zu lassen, bis sie normal ablaufen.

Dadurch wird das Leistungsproblem beseitigt, die Speicheranforderungen werden jedoch erheblich erhöht. Dies ergibt ca. 5 DelayedWeakReference für jedes Objekt, das sich tatsächlich in der Warteschlange befinden muss.

Kennt jemand eine DelayQueue mit zusätzlicher Verfolgung, die schnelle remove() -Operationen zulässt? Oder gibt es irgendwelche Vorschläge für bessere Möglichkeiten, dies zu bewältigen, ohne wesentlich mehr Speicher zu verbrauchen?

    
CuddlyDragon 16.11.2012, 16:51
quelle

3 Antworten

2
___ qstnhdr ___ DelayQueue mit höherer Geschwindigkeit remove ()? ___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ tag123performance ___ Für Fragen zur Messung oder Verbesserung der Code- und Anwendungseffizienz. ___ answer13421857 ___

Wenn ich Ihr Problem richtig verstanden habe, möchten Sie etwas für ein Objekt tun, wenn es für 5 Minuten nicht berührt wurde.

Sie können eine benutzerdefinierte verknüpfte Liste erstellen. der Schwanz ist der zuletzt berührte. Entfernen eines Knotens ist schnell.

Der Buchhaltungsfaden kann einfach alle 1 Sekunde aufwachen und Köpfe entfernen, die 5 Minuten alt sind. Wenn die Verzögerung von 1 Sekunde jedoch nicht akzeptabel ist, berechnen Sie die genaue Pausenzeit

%Vor%     
___ antwort13421088 ___


nahm mir etwas Zeit, darüber nachzudenken,
Aber nachdem du einige Minuten lang deine interessante Frage gelesen hast, hier sind meine Ideen:
A. Wenn Sie Objekte mit einer Art ID haben, verwenden Sie sie als Hash, und haben Sie tatsächlich keine Warteschlange, sondern N Verzögerungsqueues.
Dies verringert den Sperrfaktor um N.
Es wird eine zentrale Datenstruktur geben,
Halten Sie diese N Warteschlangen. Da N vorkonfiguriert ist,
Sie können alle N Warteschlangen beim Systemstart erstellen.

    
___ qstntxt ___

Ich habe ein Projekt, das die Zustandsinformationen in über 500.000 Objekten verfolgt, das Programm empfängt 10.000 Aktualisierungen / Sekunde über diese Objekte, die Aktualisierungen bestehen aus neuen, Aktualisierungs- oder Löschoperationen.

Im Rahmen des Programms müssen etwa alle fünf Minuten Hausaufgaben an diesen Objekten durchgeführt werden. Zu diesem Zweck habe ich sie in %code% eingefügt, um die %code% -Schnittstelle zu implementieren, was die Sperrfunktion von %code% ermöglicht. um das Haushalten dieser Objekte zu kontrollieren.

  • Neu wird ein Objekt auf dem %code% platziert.

  • Beim Aktualisieren wird das Objekt %code% 'd von %code% aktualisiert und dann an der neuen Position, die von den aktualisierten Informationen bestimmt wird, erneut eingefügt.

  • Nach dem Löschen ist das Objekt %code% 'd von %code% .

Das Problem, mit dem ich konfrontiert bin, ist, dass die %code% -Methode zu einer prohibitiv langen Operation wird, sobald die Warteschlange etwa 450.000 Objekte passiert.

Das Programm ist Multithread, ein Thread kümmert sich um Updates und ein anderer um die Hausverwaltung. Aufgrund der Verzögerung %code% erhalten wir fiese Probleme mit der Sperrleistung, und schließlich verbraucht der Update-Thread-Puffer den gesamten Heap-Speicher.

Ich habe es geschafft, dies zu umgehen, indem ich eine %code% erstelle, die es mir erlaubt, "Schatten" -Objekte in der Warteschlange zu lassen, bis sie normal ablaufen.

Dadurch wird das Leistungsproblem beseitigt, die Speicheranforderungen werden jedoch erheblich erhöht. Dies ergibt ca. 5 %code% für jedes Objekt, das sich tatsächlich in der Warteschlange befinden muss.

Kennt jemand eine %code% mit zusätzlicher Verfolgung, die schnelle %code% -Operationen zulässt? Oder gibt es irgendwelche Vorschläge für bessere Möglichkeiten, dies zu bewältigen, ohne wesentlich mehr Speicher zu verbrauchen?

    
___ answer13421058 ___

Wenn Sie nur ungefähr alle fünf Minuten einen Reinigungsservice durchführen müssen, ist dies nicht notwendig.

Was ich tun würde, wäre eine Aufgabe, die jede Minute (oder weniger nach Bedarf) ausgeführt wird, um zu sehen, ob seit dem letzten Update fünf Minuten vergangen sind. Wenn Sie diesen Ansatz verwenden, müssen Sie keine zusätzliche Sammlung verwalten, und bei einem Update wird keine Datenstruktur geändert. Der Aufwand beim Scannen der Komponenten ist erhöht, aber konstant. Der Aufwand für die Durchführung von Aktualisierungen wird trivial (Einstellung eines Felds mit der letzten Aktualisierung)

    
___
Yair Zaslavsky 16.11.2012, 17:00
quelle
1

Wenn Sie nur ungefähr alle fünf Minuten einen Reinigungsservice durchführen müssen, ist dies nicht notwendig.

Was ich tun würde, wäre eine Aufgabe, die jede Minute (oder weniger nach Bedarf) ausgeführt wird, um zu sehen, ob seit dem letzten Update fünf Minuten vergangen sind. Wenn Sie diesen Ansatz verwenden, müssen Sie keine zusätzliche Sammlung verwalten, und bei einem Update wird keine Datenstruktur geändert. Der Aufwand beim Scannen der Komponenten ist erhöht, aber konstant. Der Aufwand für die Durchführung von Aktualisierungen wird trivial (Einstellung eines Felds mit der letzten Aktualisierung)

    
Peter Lawrey 16.11.2012 16:58
quelle
0

Wenn ich Ihr Problem richtig verstanden habe, möchten Sie etwas für ein Objekt tun, wenn es für 5 Minuten nicht berührt wurde.

Sie können eine benutzerdefinierte verknüpfte Liste erstellen. der Schwanz ist der zuletzt berührte. Entfernen eines Knotens ist schnell.

Der Buchhaltungsfaden kann einfach alle 1 Sekunde aufwachen und Köpfe entfernen, die 5 Minuten alt sind. Wenn die Verzögerung von 1 Sekunde jedoch nicht akzeptabel ist, berechnen Sie die genaue Pausenzeit

%Vor%     
irreputable 16.11.2012 17:52
quelle

Tags und Links