java.lang.IndexOutOfBoundsException: Index: 4, Size: 5

Hab gerade mein Programm zum testen laufen gelassen und dann zeigte mir die Konsole plötzlich diesen Fehler an!

java.lang.IndexOutOfBoundsException: Index: 4, Size: 5

Teil des Programms ist es(vereinfacht gesagt)in einer Schleife Elemente aus einer LinkedList herauszuholen und anzuzeigen und dabei kam besagter Fehler…
Das ganze hat keine Performance Auswirkungen, aber es würde mich doch interessieren wie es zu so einem Fehler kommen kann!

Quellcode??

Ich greife nur ganz normal mit LinkedList_Name.get(i); darauf zu. “i” ist wie aus der Exception zu entnehmen 4!

Wird aus verschiedenen Threads auf die List zugegriffen? Wenn ja, sind diese zugriffe synchronisiert?

Index 4 Size 5? Sehr komisch, zu 99,99999% ist es meist so, dass Index >= Size ist… jedenfalls, ich hatte den Fehler auch mal, da wurde eine Liste einer bestimmten Größe erstellt aber ohne Inhalt… auf die Elemente zuzugreifen ging dann schief (allerdings bei allen Elementen, sprich schon bei 0)… allerdings kann ich sonst nicht viel dazu sagen, es ist eine halbe Ewigkeit her zu einer Zeit, wo ich noch in der Ausbildung war, seitdem nie wieder sowas gesehen.

Er versucht auf einen index zuzugreifen den es nicht gibt.
Mach nen system.out oder nutze den Debugger, solche Fehler sind meist schnell zu finden.

Bei einer Größe von 5 sollte es den Index 4 aber schon geben.
Ich setze 100 bytes auf ein Concurrency-Problem.

Concurrency-Problem = von verschiedenen Thread’s wird gleichzeitig auf die Methode zugegriffen?

Schon möglich… Müsste ich dann der betreffenden Methode ein synchronized voranstellen(habs ausprobiert, so einfach war es leider nicht ;( )?

Na ja, was vielleicht noch ganz spannend ist:
Diese Abfrage, wird(sofern meine FPS berrechnung richtig funktioniert) 900 bis 1000 mal pro Sekunde aufgerufen… Wenn ich die FPS herunterschraube kommt der Fehler viel, viel seltener!
Es erscheint fast so als wäre der Fehler Zufall und würde bei öfterem „ausprobieren“, auch öfter anfallen…
Mich wundert das alles ein wenig :wink:

[QUOTE=Marco13]Bei einer Größe von 5 sollte es den Index 4 aber schon geben.
Ich setze 100 bytes auf ein Concurrency-Problem.[/QUOTE]

Denke ich auch. Schreibe mal:

	
}```

Oder nehme gleich eine Threadsafe Datenstruktur.

Edit: Lesen von verschiedenen Threads ist kein Problem, aber wenn neue Elemente hinzugefügt werden schon. Gibt es einen besonderen Grund wieso du die LinkedList genommen hast?

Heißt das zu zeichnest mit bis zu 1000 FPS? Ist das nicht ein bisschen übertrieben?

[QUOTE=IDC;66657]Es erscheint fast so als wäre der Fehler Zufall und würde bei öfterem „ausprobieren“, auch öfter anfallen…
Mich wundert das alles ein wenig ;)[/QUOTE]
Bei Concurrency ist das Auftreten solcher Fehler zwar „zufällig“, bei falscher Implementierung aber nicht verwunderlich :wink:

Ich hatte gelesen das die LinkedList das schnellste „Array-mit-variabler-Größe“ ist, deswegen…

Wundert mich auch etwas(vielleicht bin ich auch einfach toll), vielleicht mache ich ja auch einen Grundlegenden Fehler:
Ich berechne meine FPS immer am Anfang(Wobei das ja eigentlich keinen Unterschied macht ob am Anfang oder am Ende) des GameLoop’s auf folgende Weise:


delta = System.nanoTime() - last;
last = System.nanoTime();
fps = ((long)1e9)/delta;

Ich hab außerdem noch ein Thread.sleep(1); im Loop.
(Als ich das mal Weggenommen hatte, hatte ich plötzlich FPS von 3000 - 276000 und da dachte ich mir auch so: Na ob das mal stimmt… Aber da mir die FPS ja relativ gleichgültig ist und mich nur delta Programm-technisch interessiert hab ich es dann ignoriert :wink: )

Welche List am schnellsten oder besten ist, hängt davon ab, welche Operationen man darauf durchführt. Wenn du oft Elemente am Anfang einfügst und entfernst, mag das passen, ansonsten ist ArrayList eigentlich „„Standard““.

Die FPS… zu zählst vielleicht die Schleifendurchläufe, und vielleicht auch wie oft „repaint“ aufgerufen wird, aber vermutlich nicht die FPS :wink:

Ähh, korrigier mich:
Wenn ich zähle wie oft repaint pro Sekunde aufgerufen wird, dann habe ich doch die FPS!?

[QUOTE=IDC]Ähh, korrigier mich:
Wenn ich zähle wie oft repaint pro Sekunde aufgerufen wird, dann habe ich doch die FPS!?[/QUOTE]
Korrektur: Wann man zählt wie oft paint/paintComponent einer Komponente aufgerufen pro Sekunde, erhält man die FPS. Der Aufruf von repaint ist nur ein Wunsch an den RepaintManager, die Komponente bitte neu zu zeichnen. Letzterer puffert u.U. solche repaint Aufrufe.

Ist das nicht ein bisschen knapp und Du erzeugst ziemlich viel Last? Würde ein sleep von 10ms nicht ausreichen? Oder Du machst das ganze Abhängig vom der vergangenen Zeit seit dem letzten Neuzeichnen ( != letzter repaint() Aufruf)

[QUOTE=_Michael;66749]
Ist das nicht ein bisschen knapp und Du erzeugst ziemlich viel Last? Würde ein sleep von 10ms nicht ausreichen?[/QUOTE]
Ja, hab ich auch normalerweise so, wollte es nur mal getestet haben was möglich ist und was dann passiert…

also solche FPS-zahlen bekommt man auch bei modernen auf OpenGL bzw DirectX laufenden games hin, man muss nur genug in die hardware investieren
ich hab mir vor ca 2 wochen ein neues system zusammen gebaut und komme bei aktuellen top-spielen auch locker auf 600 bis 700 FPS auch wenn für solche extreme mein system schon unter 110% volllast läuft und recht laut wird
warum solche zahlen nicht also auch mal eben in java mit hardware-beschleunigung erreichen ? sicher, swing mit double-buffering ist schon noch was anderes als echtes 3d-rendering über z.b. jogl/lwjgl, aber wenn man auf v-sync verzichtet (was bei mir grundsätzlich der fall ist) ist es so ziemlich egal das auch große flats nur 60Hz bis 75Hz schaffen
übertrieben würde ich solche zahlen nicht halten, vielleicht nur etwas ungenau berechnet

Mal nebenbei: Wenn da ein Thread.sleep(1); drinsteht und das ganze 1000 gemacht wird, ergibt DAS allein schon 1 Sekunde. Aber ein Thread.sleep(1) kann/muss ja nicht wirklich 1ms sleepen. Sooo genau ist das nicht.

Wie schon angedeutet wurde: Wenn man sowas macht wie

for (int i=0; i<1000; i++) {
    someComponent.repaint();
}

dann wird das ganze nur wenige Millisekunden dauern, und danach wird die Component vielleicht EIN mal neu gezeichnet. (Oder auch mehrmals, das weiß man nicht, aber sicher nicht 1000 mal).

@Unregistered: Da muss man einige Dinge berücksichtigen. Es gibt mindestens 2 IMHO sinnvolle Interpretationen von “FPS”. Entweder man berechnet die “theoretischen” FPS aus der Zeit, die benötigt wird, um “alles zu zeichnen”

void draw()
{
    long before = System.nanoTime();
    drawEverything();
    long after = System.nanoTime();
    fps = compute(before, after);
}

oder man berechnet die “echten” FPS, indem man mitzählt, wie oft pro Sekunde neu gezeichnet wird

long previous = System.nanoTime();
void draw()
{
    drawEverything();
    long current = System.nanoTime();
    fps = compute(previous, current);
    previous = current;
}

Beides hat einige caveats. Beim ersten weiß man im Endeffekt nicht, ob Zeichenbefehle, die in “drawEverything” ausgeführt werden, vielleicht noch irgendwie gepuffert werden (bzw. ob dann noch was passieren muss, bis die Daten wirklich auf dem Bildschirm zu sehen sind). Beim zweiten weiß man nicht, ob der limitierende Faktor das zeichnen ist, oder schlicht die Tatsache, dass ‘draw’ nicht oft genug aufgerufen wird.

Dazu kommt noch, dass Swing schon sehr weit von der Zeichen-Pipeline abstrahiert. Mit OpenGL ohne Vsync kriegt man solche Zahlen hin, aber durch die Hardwareunabhängigkeit ist Swing prinzipedingt eine viel dickere Abstraktionsschicht, und da “richtige” oder auch nur “sinnvolle” FPS zu messen kann etwas fummeliger sein…

600-700? Aha, was hast denn da rumstehen, nen Großrechner mit 20 paralel laufenden Titan Gakas oder wie? Bei mir laufen ältere Spiele wie Skyrim bei 4k HD Texturen bei 200FPS, neuere Speile die weniger Hardwarehungrig sind wie WarThunder bei 150 und bei AsassinCreed BlackFlag 80. Ich könnte zwar von meiner 780 auf ne Titan umsteigen, oder Sli (falls das geht), und von 4x4ghz auf 16x4ghz, aber ne Steigerung um 500% würde ich damit trotzdem net erreichen.

…ich vermisse nen Off-Topic Tag

[QUOTE=mla.rue;66790]
…ich vermisse nen Off-Topic Tag[/QUOTE]
Egal, ich lese mir sowieso alles durch, also bemerke ich schon wenn noch mal was zum eigentlichen Thema kommt… :wink:
Also ich glaube ich hab ne Idee wie diese FPS zahlen zustande kommen könnte(!):
Die FPS schwanken zwischen 998(oder 999) und 1000!
Jetzt ändert sich, selbst wenn ich w, a, s oder d drücke, nur jedes 2te, 3te mal etwas am Endbild.
Ich weiß nicht wie intelligent repaint() ist, aber es wäre doch möglich das es gar nicht zeichnet wenn sich nichts ändert… ?
Daher die 1000…
Wenn sich etwas ändert dann sind die FPS eben nur bei 999 usw…
Ist nur so eine Idee muss nicht unbedingt stimmen!

Edit: Wenn jemand noch was zu der Ursprungsfrage sagen kann, die ist immer noch aktuell

Edit 2: Skyrim is doch nicht alt!?

Zur Ursprungsfrage… da gibt es IMHO erstmal zwei Möglichkeiten:

  1. Derjenige, der die LinkedList implementiert hat, hat einen übelst-stümperhaften Bug eingebaut, und Millionen von Programmierern haben das in den letzten 20 Jahren nicht bemerkt ODER
  2. Das ist ein Concurrency-Problem.

Nach dem Gießkannenprinzip synchronized’s einzustreuen ist nicht ratsam. Poste vielleicht mal den Code, zumindest die Stellen, wo die Liste verwendet wird - vielleicht erkennt man daran schon was…