Ich bin grade dabei eine Java-Anwendung zu schreiben die mehrere (hier
24) Threads startet um Dokumente mit Apache FOP zu erzeugen.
Das grobe Gerüst ist:
Ein Thread hat eine Liste (ArrayList oder Vector, beides probiert), und
stellt eine synchronized Methode getNextDocument() bereit.
Die (24) Generatorenthreads rufen getNextDocument() in einer loop in
ihrer jeweiligen run() Methode, sind bei der Bearbeitung des Datenpakets
350-500ms beschäftigt, updaten dabei Datenfelder im Objekt das mit
getNextDocument() geliefert wurde, und wenn sie fertig sind rufen sie
wieder getNextDocument() bis der Aufruf null zurück gibt.
Während dieser Zeit gibt es keine Netzwerk- oder Dateisystemzugriffe -
das Programm hat alle Daten im RAM und verarbeitet sie.
Jetzt stößt mir ein wenig bitter auf, dass die Prozesse so viel Sys-Load
machen. User-Load wäre so weit ich das verstanden habe ok - dann macht
das Programm was, aber Sys-Load bedeutet doch Kontext-Switches,
Speicherallokierung, oder anders gesagt: Zeit die der Kernel braucht,
und die dem Programm nicht zur Verfügung steht.
Dazu kommt das ich mich nicht erinnern kann den gleichen Sys-Load im POC
Progrämmchen zu haben - das auch schneller mehr Dokumente erzeugte.
Irgendwie irgendwo hat sich beim schreiben des eigentlichen Programms
ein Fehler eingeschlichen, der mir ordentlich Performace klaut… nur… wo?
Anbei Bildchen:
1. htop Anzeige der Prozessorbelastung. Grün ist OK, User-Land, rot ist
böse.
2. dstat zeigt htop kumuliert. Auffällig sind die vielen Interrupts.
3. irqstats. Hier gehen bei der Generierung die "Local Timer
Interrupts", und die "TLB Shootdowns" hoch. Liegt hier das Problem? Wenn
ja, welcher Teil von Java macht sowas? Analysemöglichkeit? Lösung?
4. VisualVM Trace während des Programmablaufs (RAM Rampe am Anfang ist
"Daten holen", der Rest ist "Generierung" mit den beschriebenen
Symptomen). Auffällig hier: Es kann nicht am GC liegen, der dümpelt nur
so vor sich hin.
Kann mir da jemand weiter helfen? Schon mal ähnliche Probleme gehabt?
24) Threads startet um Dokumente mit Apache FOP zu erzeugen.
Das grobe Gerüst ist:
Ein Thread hat eine Liste (ArrayList oder Vector, beides probiert), und
stellt eine synchronized Methode getNextDocument() bereit.
Die (24) Generatorenthreads rufen getNextDocument() in einer loop in
ihrer jeweiligen run() Methode, sind bei der Bearbeitung des Datenpakets
350-500ms beschäftigt, updaten dabei Datenfelder im Objekt das mit
getNextDocument() geliefert wurde, und wenn sie fertig sind rufen sie
wieder getNextDocument() bis der Aufruf null zurück gibt.
Während dieser Zeit gibt es keine Netzwerk- oder Dateisystemzugriffe -
das Programm hat alle Daten im RAM und verarbeitet sie.
Jetzt stößt mir ein wenig bitter auf, dass die Prozesse so viel Sys-Load
machen. User-Load wäre so weit ich das verstanden habe ok - dann macht
das Programm was, aber Sys-Load bedeutet doch Kontext-Switches,
Speicherallokierung, oder anders gesagt: Zeit die der Kernel braucht,
und die dem Programm nicht zur Verfügung steht.
Dazu kommt das ich mich nicht erinnern kann den gleichen Sys-Load im POC
Progrämmchen zu haben - das auch schneller mehr Dokumente erzeugte.
Irgendwie irgendwo hat sich beim schreiben des eigentlichen Programms
ein Fehler eingeschlichen, der mir ordentlich Performace klaut… nur… wo?
Anbei Bildchen:
1. htop Anzeige der Prozessorbelastung. Grün ist OK, User-Land, rot ist
böse.
2. dstat zeigt htop kumuliert. Auffällig sind die vielen Interrupts.
3. irqstats. Hier gehen bei der Generierung die "Local Timer
Interrupts", und die "TLB Shootdowns" hoch. Liegt hier das Problem? Wenn
ja, welcher Teil von Java macht sowas? Analysemöglichkeit? Lösung?
4. VisualVM Trace während des Programmablaufs (RAM Rampe am Anfang ist
"Daten holen", der Rest ist "Generierung" mit den beschriebenen
Symptomen). Auffällig hier: Es kann nicht am GC liegen, der dümpelt nur
so vor sich hin.
Kann mir da jemand weiter helfen? Schon mal ähnliche Probleme gehabt?