# DatagramSocket  Problem mit Verabeitungsgeschwindigkeit



## RobDom (26. Sep 2007)

Hallo zusammen,

habe ein Performance Problem bei Daten über eine UDP.

Ich bekomme aus einer Steuerung alle 20ms ein 1200 Byte Packet,
jetzt lese ich die Daten über DatagramSocket ein und speichere sie
anschließend in Arrays, um dann damit java3D Transformationen zu setzen.

Leider ist die Grafikdarstellung etwas ruckelig und ich habe festgestellt, dass
das nur so ist, wenn das Datenlesen läuft. Dann habe ich mir mal ein paar
Zeitstempel gemacht und festgestellt, dass das laden der Daten DatagrammSocket.receive
zwischen 40ms und mehreren hundert ms dauert, und auch teilweise Packete vertauscht werden.

Hier ein Code-Ausschnitt:



```
public class connection implements Runnable{
	
private static DatagramPacket datagramPacket = null;
private static DatagramSocket datagramSocket = null;
private static byte[] inbuffer = new byte[1200];
private static ByteBuffer byteBuffer = ByteBuffer.allocate(1200);
public static boolean loaded = false; 

		
public static void setIP() {
		
	if (useStandard) {
		try {	 
			IP = InetAddress.getLocalHost().getHostAddress();
		} 
		catch (UnknownHostException e) {
				
		} 
	}
	
} // end setIP


public static void initConnection() {
		
	datagramPacket = new DatagramPacket(inbuffer, inbuffer.length);
		
	// Initialize SocketConnection
	try {
		setIP();
		InetAddress address = InetAddress.getByName(IP);
		datagramSocket = new DatagramSocket(port, address);
	} 
	catch (UnknownHostException e) {
		openMainFrame.console.append("\nERROR:  UnknowHostException\n" + e.toString() + "\n");
	} 
	catch (SocketException e) {
		openMainFrame.console.append("\nERROR:  SocketException\n" + e.toString() + "\n");
	}
		
	// Timeout Recieve Data
	try {
		datagramSocket.setSoTimeout(1000);
			
	} 
	catch (SocketException e) {
		openMainFrame.console.append("\nERROR:  SocketException\n" + e.toString() + "\n");
	}
		
	try {
		openMainFrame.console.append("\nTimeout: " +datagramSocket.getSoTimeout());
	} 
	catch (SocketException e) {
		openMainFrame.console.append("\nERROR:  SocketException\n" + e.toString() + "\n");
	}	
		
} // end initConnection


public void run (){
		
	while (true){
		if (Thread.interrupted()) {
			break;
		}
			
		try{
			Thread.sleep(transmissionRate);
		}
		catch (Exception e){}			
			
		// Receive Data
		try {
						
			datagramSocket.receive(datagramPacket);  
		} 
		catch (IOException e) {
		                try {
			                Thread.sleep(1000); 
		                } 
		                catch (InterruptedException ex) {
			                openMainFrame.console.append("\nERROR:  InterruptedException\n" + ex.toString() + "\n");
			}			
			openMainFrame.console.append("\n... receive tried to execute");
		}
			
		// Read Data
		String[] fileName = {"", "", "", "", "", "", "", "", "", ""};
		char[][] readName = new char[10][32];
		float[][] position = new float[10][6];
		float[][] tcp = new float[10][6];
		float[][] axisData = new float[10][10];
		int end[] = new int[10];
			
		byteBuffer = ByteBuffer.wrap(inbuffer, 0, 1200);
						
		for (int i=0; i<10; i++) {
			// Filename
			for (int j=0; j<32; j++) {
				readName[i][j] = (char)byteBuffer.get(j+i*120);
				if ((char)byteBuffer.get(j+i*120) == ''){
					end[i] = j;
					break;
				}
			}
				
			for (int k=0; k<end[i] ;k++) {
				fileName[i] = fileName[i] + String.valueOf(readName[i][k]);
			}
			
			// Machine Position
			for (int j=0; j<6; j++) {
				position[i][j] = byteBuffer.getFloat(32+j*4+i*120);
			}
			
			// TCP Position
			for (int j=0; j<6; j++) {
				tcp[i][j] = byteBuffer.getFloat(56+j*4+i*120);
			}
				
			// Axis Data
			for (int j=0; j<10; j++) {
				axisData[i][j] = byteBuffer.getFloat(80+j*4+i*120);
			}
	
                            // usw. ab hier Grafiksteurung...
} // end run
```

Ich habe schon probiert die Grafikvearbeitung, das Schreiben der Daten in die Arrays, usw.
auszukommentieren und es ist immer noch genauso langsam. Die Rechenzeitprobleme kommen
aus Zeile 76 !!
Mein Problem:
- Performance, ich schaffe es nicht alle 20ms die 1200Byte zu empfangen und zu verarbeiten.
- Zuverlässigkeit, es werden Packete "verschluckt" oder vertauscht.

Hab ich irgendwas falsch gemacht oder vergessen?? Oder hat jemand eine andere schnellere Idee??

Danke und Gruß


----------



## tuxedo (26. Sep 2007)

Versuch doch mal dein empfangen der Pakete in einen Thread auszulagern und somit das triggern der 3D-Sache zu entkoppelt. Weil ein "datagramSocket.receive(datagramPacket);  " blockiert dein Programm solange bis das Paket zuende gelesen wurde... Die restliche Anwendung sollte deshlab von dieser Wartezeit entkoppelt sein.

UDP ist von Haus aus unzuverlässig was die Reihenfolge der Pakete, sowie die Zustellung überhaut angeht. Es liegt also an dir auf "verschluckte" Pakete richtig zu reagieren bzw. die Reihenfolge der Pakete nach dem Empfang zu korrigieren.

- Alex


----------



## RobDom (26. Sep 2007)

Ich habe schon versucht das Laden und den Grafikaufbau zu entkoppeln,
indem ich beides aus verschiedenen Klassen starte. Dann müssten doch eigentlich 
die Threads schon unterschiedlich sein, odder??

Außerdem weiß ich nicht welche Prioritäten ich legen muss, ob aufs Daten laden,
oder auf den Grafikaufbau?? Eigentlich muss ich ja korrekte Daten empfangen,
um dann danach die Grafik zu setzen.

Zum "verschlucken" und vertauschen: Die Daten kommen in korrekter Reihenfolge
an, wenn ich die Grafik ausschalte, wenn ich sie wieder einschalte entstehen Fehler.

Könntest Du mir vielleicht ein kurzes Codebeispiel zum Thread trennen schreiben,
bzw. was Du damit meintest, kenne mich mit Threads nicht so gut aus :lol: , bin
eher für die 3D Geschichten zuständig...

Danke und Gruß


----------



## tuxedo (26. Sep 2007)

ZUm Thema Thread schreib ich hier nicht nochmal ein Beispiel. Zum einen gibts das tausenddfach hier im Forum, zum anderen steht das wirklich gut beschrieben sowohl in "Java ist auch eine Insel" als auch im "Java Buch". Beides gibts im Netz zum kostenlosen runterladen.

Einfach die Dinge in eine eigene Klasse stecken entkoppelt das ganze noch nicht. Du wirst deine "vom Netzwerk lesen" Geschichte in einer Klasse die von Thread erbt oder runnable implementiert laufen lassen müssen. 

Meld dich wieder wenn du dich n bisschen bzgl. Threads informiert hast und die nächsten Probleme auftauchen.

- Alex


----------



## RobDom (26. Sep 2007)

...es ist ja nicht so, dass ich nicht wüsste worum es geht,
ich hab auch schon folgendes ausprobiert:


```
private static class loader extends Thread {
				
                public void run(){
	                while (!Thread.interrupted()){
		                try {				
			                datagramSocket.receive(datagramPacket); 	
		                } 
		                catch (IOException e) { }
		}
	}

}


// und dann in der run:

Thread thread =new Thread();
thread.setPriority(priority);
thread = new loader();
```

...aber das bringt leider nix.

Mit Beispielprogramm meinte ich nicht, wie man Threads verwendet,
sondern, ob Du eine Idee hast wie man das am besten realisieren kann.

Leider weiß ich auch nicht, wieviele Threads von wo aufgerufen werden
und welcher welche Prioritäten hat und ob es überhaupt was bringt, selber
ein paar Threads zu benutzen, wo im Hintergrund hunderte laufen...???

Ich habe nur festgestellt, dass wenn ich Werte aus java übernehme, z.B.
aus Scrollbars dann läuft die Grafik superschnell, aber sobald ich Date lese
fangen die Probleme an. Gibt es eigentlich zum DatagrammSocket alternativen??

DAnke und Gruß


----------



## tuxedo (26. Sep 2007)

Wenn du an UDP gebunden bist: Nein...

Problem ist: die Lese-Methoden sind (fast) alle blockierend. Ausnahme ist hier Java NIO. 

Beispiel bzgl blockierend:

Du hast z.B. folgende Schleife

while(abbruchbedingung){
 lese vom netzwerk -> blockiere bis Datenpaket vollständig da ist
 zeichne
}

Wenn du's so in der Art gelöst hast, dann steht der Rest des Programms jedesmal wenn das lesen etwss länger dauert. Sinnvoller wäre es du machst in etwa folgendes:

Startklasse:
 starteZeichenKlasse
 starteNetzwerkThread(zeichenKlasseObjekt)

ZeichenKlasse hat d.. z.B. folgende Methode
 fügeNeueDatenEin(Daten d)

Und dein Thread macht z.b. folgendes:
run(){
 Daten d = leseDatenVomNetzwerk();
 zeichenKlasseObjekt.fügeneueDatenEin(d);
}

Schuld an der Sache ist nicht der DatagramSocket... Schuld daran ist die etwas nachlässige Programmierung des rests.



```
Thread thread =new Thread();
thread.setPriority(priority);
thread = new loader();
```

Das ist mehr oder wneiger Blödsinn.. Erst erstellst du ein "thread" Objekt vom Typ "Thread", setzt eine Priorität, und dann überschreibst du es mit einer Instant von "loader" ... Da hättest du dir die ersten 2 Zeilen auch sparen können. 

BTW: Extra eine Priorität setzen ist in den meisten Fällen nicht notwendig.


----------



## sparrow (26. Sep 2007)

Außerdem sehe ich hier keinen "Start" des Threads.


----------



## tuxedo (27. Sep 2007)

Jetzt wo du's erwähnst... Ja, der fehlt auch noch.


----------



## RobDom (27. Sep 2007)

... hab das ganze jetzt mal etwas umgestrickt, in etwa so:


```
public class main{
	
public static Thread t = null;	
	
public static void main(String[] args) {
	t = new Thread(new graph());
	t.start();
}
		
} // end class
	

public class graph implements Runnable{

public static connection  simulation = new connection();
public static Thread threadSimulation = new Thread(simulation);
public static boolean geladen = false;

public static void move() {
                threadSimulation = new Thread(simulation);
                threadSimulation.start();
                // ...Graph laden
                geladen = true;
}

public void run (){
		
	while (true) {
		repaint();
		if (geladen){
                                // ...Graph verändern
                                }
                }
}

} // end class


public class connection implements Runnable{

public void run (){
		
	while (true) {
		// ...Daten laden
                }
}

} // end class
```

das bringt genau nix!

dann hab ich noch versucht die beiden gegenseitig auszusetzen,
indem ich die beiden run() wie folgt verändert hab:


```
while (!graph.boolInterupt) {
                boolInterupt = true;
                // ... Daten laden
                boolInterupt = false;
                if (main.t.isInterrupted())threadSimulation.start();
}

//und

while (!connection.boolInterupt) {
                boolInterupt = true;
                // ... Graph ändern
                boolInterupt = false;
               if (threadSimulation.isInterrupted())threadSimulation.start();
}
```

... dann wird zwar geladen, aber nicht mehr bewegt.

Da ist doch bestimmt schon wieder etwas falsch ?!?
Wenn ich mir in jeder run() eine Zeile ausgebe, sehe ich,
daß die beiden nicht abwechselnd, sonder durcheinander abgearbeitet werden...


----------



## tuxedo (27. Sep 2007)

Ich glaub du hast die Sache mit den Threads noch nicht verstanden... und ständig nen Thread anhalten und starten ist auch nicht Sinn der Sache.. Ich klopf dir mal geschwind ein Beispiel zusammen.... momentchen.


----------



## tuxedo (27. Sep 2007)

Sooo, bitteschön.


```
public class Zeichenklasse {
	
	/*
	 * Ein von mir erdachtes Pseudo-Objekt das die Daten zum Zeichnen vorhält
	 */
	Data d;
	
	
	public Zeichenklasse() {
		// hier kannst du meinetwegen die Zeichenoperation initialisieren
		// und auch die Methode "updateZeichung" beispielsweise in einer 
		// Endlosschleife triggern
	}
	
	public void updateZeichnung(){
		/*
		 * Hier werden weitere Methoden und Funktionen ausgeführt um die
		 * Zeichnung auf den neusten Stand zu bringen
		 * Die Zeichenoperation bedient sich dabei der Daten aus "d"
		 */
	}
	
	/*
	 * Diese Methode wird vom ConnectionThread aufgerufen
	 * um der Zeichenklasse neue Daten zu übermitteln
	 */
	public void addData(Data d){
		this.d=d;
	}
	
	public static void main(String[] args) {
		Zeichenklasse zk = new Zeichenklasse();
		ConnectionThread ct = new ConnectionThread(zk);
		ct.start();
		
	}

}
```


```
public class ConnectionThread extends Thread {

	Zeichenklasse zk = null;
	
	public ConnectionThread(Zeichenklasse zk) {
		this.zk=zk;
	}
	
	@Override
	public void run() {
	
		/*
		 * Lese Daten vom Netzwerk und Speichere sie im
		 * Pseudo-Datencontainer "Data"
		 */
		Data d;
		
		while(!interrupted()){
			
			// hier musst du natürlich auf deine Art und Weise vom Netzwerk lesen
			d = netzwerk.read();
			
			// hier werden neue Daten der Zeichenklasse übermittelt
			zk.addData(d);
			
		}
	
	}

}
```

Die Klasse ConnectionThread holt, unabhängig vom rest des Programms (welches im Main-Thread [jedes Programm hat einen Main-Thread] läuft), so schnell wie möglich die Daten vom Netzwerk und übergibt sie der Zeichenklasse.
Zum aktualisieren der Zeichnung kannst du "egal wo", beispielsweise in einer Art Endlosschleife, die updateZeichnung()" aufrufen.

Das war's eigentlich schon. Nix mir "Thread hier starten, dort wieder Stoppen, ..."

- Alex


----------



## RobDom (27. Sep 2007)

...Danke, dass Du Dir so viel Mühe mit mir gibst   
aber ich glaube, wir reden aneinander vorbei.

Was Du gerade geschrieben hast hatte ich ja schon:

1. Main Klasse die Thread Connect Klasse startet und in einer Schleife die Grafik aktualisiert.

- Dann läuft das laden der Daten in einem unabhängigen Thread und der Grafikaufbau im Main Thread.
- Problem das Laden der Daten dauert ca. 40-100ms, der Grafikaufbau erfolgt schneller, -->Ruckeln

Dann hab ichs umgeschrieben:

2. Main Klasse, und zwei Thread Klassen connect und draw, eine läd im eigene Thread, die andere
updatet Grafik im eigene Thread. BEide werden von main aufgerufen und laufen unabhängig.

- Welche von beiden starte ich zuerst?? Vergebe ich Prioritäten?? Verwende ich Sleep??
- irgendwie muss ich ja das ganze synchronisieren, sonst lese ich Daten, die nicht verwendet werden,
oder update den Graph mit alten Daten.
- Welcher Thread hat vorrang, welcher braucht länger...??

Dann hatte ich die Idee:

3. Die beiden Threads gegeneienander verriegeln und immer wieder abwechselnd zu stoppen und zu starten

- Idee: Laden, Thread Laden.stop, Thread Grafik.start, Grafikupdate, Thread Grafik.stop, Thread Laden.start, Laden, usw.
- aber das geht wohl so nicht!?!


Mein Problem ist:
Wenn Laden und Grafikaufbau gleichzeitig laufen, egal ob in einem Thread main, oder in zwei getrennten,
oder eins in main und das andere separat, dann ist entweder die Grafik ruckelig, oder die Daten werden
durcheinander geschmissen.


----------



## tuxedo (27. Sep 2007)

Vielleicht sollten wir uns mal darüber unterhalten was du zeichnest und was die ankommenden Daten bei der Zeichnung bewirken. 

Weil:

Wenn die ankommenden Daten dazu genutzt werden um irgendetwas  zu bewegen/animieren das einem Video gleich kommt, dann leuchtet mir das Problem ein. Weil dann sind die Daten echtzeitsensitiv. 

Ich bin davon ausgegangen dass es sich um Bewegungs oder Steuerdaten handelt wie man sie Beispielsweise von Onlinespielen kennt. Ob da die Figur unterwegs kurz anhält oder erst 500ms später losläuft oder ankommt ist da ja quasi zu vernachlässigen.

Echtzeitsensitive Daten (normalerweise Audio oder Videodaten) die über's Netz geschicht werden, sollten mit einem entsprechenden Protokoll versehen werden, z.B. Realtime Streaming Protocol. 

Oder, wenn es die implementierung erlaubt und du weniger das Internet und vielmehr ein lokales Netzwerk nutzt, einfach TCP nehmen. Da geht nix verloren und die Reihelfolge stimmt auch. Das ganze wird jedoch etwas langsamer in der Übertragung weil TCP etwas mehr Overhead produziert als UDP. Aber in einem 100MBit-Netzwerk spielt das keine Rolle.

Also, poste halt mal was du da treibst und wie man sich das gesamte vorstellen muss.

- Alex


----------



## RobDom (27. Sep 2007)

...wenns denn hilft, hier ein paar Infos:

Es handelt sich um eine industrielle Robotersimulation.
Ich erhalte Daten aus einer Steuerung, deshalb muss es UDP bleiben.

Ich erstelle einen java3D SceneGraph (das Robotermodell), wobei dort auch Daten aus CAD-Modellen
importiert werden können, der Graph an sich ist also etwas komplex.

Über die Schnittstelle empfange ich folgende Daten: Projektname, um ein Projekt zu laden; Anzahl und Position
des/der simulierten Roboters im Raum; bis zu 10 Achswinkel pro Roboter (float); insgesamt 1200 Byte alle 20ms

Mit diesen Daten lade und erstelle ich zuerst die Modelle (SceneGraph), berechne dann in mehreren weiteren
Klassen die Achstransformationen aus den Achswinkeln (auch schon relativ komplexe Klassen).

Diese Transformationen werden dann in Echtzeit mit den Trafos des SceneGraph multipliziert, um
schließlich die Bewegung, die die Steuerung vorgibt, simuliert am Modell darzustellen.

Natürlich gibt es noch weitere verlamgsamende Funktionen, wie Navigation / Perspektive, Erstellung von
Tracespuren, Kräfte- und Beschleunigungsdiagramme, etc.

Das ganze Programm ist etwas größer, deshalb kann ich auch immer nur Datenschnipsel posten!

Aber wie gesagt, alles läuft sehr schnell und flüssig, wenn ich entweder das Datenlesen auskommentiere
und selber z.B. aus einer Schleife Winkel von 0-360 vorgebe, oder nur die Daten einlese, aber keine Echtzeit
Grafikdarstellung fahren lasse.

Es gibt auch einen Handbetrieb, wo man alle Achsen einzeln über Scrollbars, Buttons, Textfeldeingabe
steuern kann, da läuft die Grafik superflüssig (und ich kann mit einer Scrollbar auch sehr schnell 360° abfahren,
in dem ich sie von links nach rechts reiße, da gibt es kein Problem mit der Grafik).

Also vermute ich, dass das Datenlesen irgendwie mit dem Grafikaufbau in die Quere kommt.

Ich hoffe, dass vermittelt einen kleinen Eindruck und bringt Dich vielleicht auf alternative Ideen.
Nochmals Danke, Du hast mir schon sehr geholfen, an der richtigen Stelle zu suchen.

Gruß RobDom


----------



## tuxedo (27. Sep 2007)

Das ruckeln kommt nicht wirklich durch das lesen vom Netzwerk zustande... 

Du wirst ja nicht pro empfangenen Datenpaket das Projekt neu laden oder ständig die Roboter neu in den Szenengraph einfügen. Ich hoffe mal so schlau warst du schon. Wenn nicht: -> ändern... 

Wenn du also nach den ersten Paketen deinen Szenengraph erstmal erstellt hast und eiigtl nur noch die Achswinkel von bedeutung sind, dann versteh ich nicht was da ruckeln soll... Eins ist auch klar:
Eine Flüssige bewegung hast auf ab 25..30 Frames. Aber jetzt Frames nicht bezogen auf den Bildaufbau (der ist ja wie du schon gesagt hast sehr schnell und flüssig), sondern auf das updaten der Bewegung. 

Du sagst du erhält alle 20ms ein Datenpaket? Das wären dann sogesehen 50 Stück pro Sekunde, womit du den Roboter 50mal pro Sekunde aktualisieren könntest.

Am besten schreibst du mal ein kleines Testprogramm dass einfach immer die 1200bytes entgegen nimmt und mal stoppt wieviele es pro Sekunde empfangen kann (oder die zeit zwischen 2 Paketen messen). Damit die Bewegung des Roboters flüssig läuft sollte die Zeit pro Paket nicht über 33ms liegen. 

Wenn du dann an dem Paket noch rumrechnen musst um die Transformation zu erhalten (konnte ich auch deinem text jetzt nicht entnehmen, ob du nur komplex rechnen musst wenn du die Daten aus dem Paket ziehst oder auch wenn du den Roboter manuell bewegst), dann kommst du unter Umständen schnell über 33ms, je nachdem wie komplex die Rechnung ist. Und dann wäre das der Grund für's ruckeln.

Wenn du also ausschließen kannst dass

a) die Pakete zu langsam ankommen 
b) die berechung der Transformation aus den Daten des Pakets zu lange dauert

dann müssen wir das ganze weiter eingrenzen.


----------



## RobDom (28. Sep 2007)

...natürlich lade ich die Modelle nicht jedesmal neu, die sind fertig und kompiliert
und nur noch die capabilities zum setzen der Transformationen ermöglichen Veränderungen.
Das ist also nicht das Problem.

Hab gestern nochmal einiges ausprobiert:
1. Zeitstempel vor/nach Laden, Einlesen, Rechnen, Trafo setzen.
Das Ganze dauert im Schnitt 16ms und ist ziemlich konstant, also auch ok.
Ich benutze ja auch die gleichen Berechnungen im Handbetrieb.
2. Ich hab im Handbetrieb (über Scrollbars) mal einfach das Laden der Daten
und Einlesen in Arrays mitlaufen lassen, die DAten aber nicht verwendet.
Das war genauso schnell, wie sonst auch bei Hand.

Also: Du hast recht, das Lesen der Daten ist es nicht, sonst müsste Hand ja auch langsamer werden.
Ich werde also mal auf die Suche gehen, ob ich in den beiden Algorithmen etwas unterschiedlich 
gemacht habe, was die Probleme auslöst.

...und wieder hast DU mich auf die richtige Fährte gebracht... :lol:


----------



## RobDom (28. Sep 2007)

...hab grad noch eine Test gemacht:

Hab die Daten gleichzeitig an zwei unterschiedlich schnelle PCs geschickt.
Der langsame ruckelt wie vorher, der schnelle ist flüssiger.

Dabei bin ich auf noch etwas gestoßen:

1. Unterbreche ich die Daten, bleibt der schnelle direkt stehen, der langsame fährt weiter
(hängt in der Bewegung dem schnellen hinterher, läuft weiter bis zur Position, in der der schnelle
auch angehalten hat) und stopp dann.
2. Auch auf dem schnelleren läuft die Bewegung und stoppt kurz zyklisch ca. alle 2 sek.

Das lässt mich doch vermuten, dass ich Probleme mit Speicher / Puffer habe. Die Daten werden
alle eingelesen und auch der Reihe nach verarbeitet, nur anscheinend läuft da beim Grafik verarbeiten
irgendwas voll.

Vielleicht hilft das noch:
Ich starte das ganze aus Eclipse 3.2.2 und habe dort aufgrund von früheren Problemen
(Heap OutOfMemoryExceptions) schon den Heap der VM erhöht: -vmargs -Xms 256m -Xmx 1024m
(von 40m / 256m).

Kann es also sein, dass meine Grafik Probleme mit Speicher / Puffer / Heap / Stack / Eclipse zu tun hat???


----------



## tuxedo (28. Sep 2007)

Du könntest mal mit "-verbose:gc" Ausgaben den GC auf der Console beobachten ... Oder du benutzt das dem JDK beiliegende "JConsole" um das ganze mal zu überwachen.

Da du schreibst, dass der schnelle PC sofort stehen bleibt wenn keine Daten mehr ankommen, würde ich daraus schließen, dass die Berechnung zu langsam läuft, bzw zu rechenintensiv ist. Naja, vielleicht nicht unbedingt rechenintensiv. Aber wenn du beispielsweise in einer while oder for-schleife oft ein "= new Xyz()" oder sowas machst, musst jedesmal Speicher allokiert werden. In solchen Schleifen deshlab den "new" Operator vermeiden. Vielleicht hilft dir das ...

- Alex


----------



## RobDom (28. Sep 2007)

... es sind keine überflüssigen new in Schleife, nur an einer Stelle und das ist notwendig.



> Du könntest mal mit "-verbose:gc" Ausgaben den GC auf der Console beobachten ... Oder du benutzt das dem JDK beiliegende "JConsole" um das ganze mal zu überwachen.



Kannst Du das etwas genauer erklären bitte.

Mir ist noch aufgefallen, dass ich die Anzeige von Hand und Auto in zwei verschiedenen Fenstern
(JFrame, Canvas3D) darstelle, kann es damit noch was zu tun haben??

Kann es sein, dass Speicher voll laufen ??
Denn auch auf dem schnellen PC läuft es eine Weile flüssig, dann stockt es kurz, dann läuft es wieder flüssig, usw.


Bin jetzt erst mal 2 Wochen in Urlaub, also nicht wunderen, wenn keine Antworten mehr kommen :wink: 

Gruß und Dank RobDom


----------



## tuxedo (28. Sep 2007)

Wenn du der JVM beim starten "-verbose:gc" mitgibst, hast du auf der COnsole ne Ausgabe wieviel Speucher gerade in Benutzung ist und allokiert bzw. wieder freigegeben wird. Damit kannst du schonmal schauen ob der Speicher voll läuft. 

Bei Java ist ein Programm im "bin" Ordner namens "JConsole". Damit kannst du dich in einen laufenden Java Prozess einklinken und diesen Analysieren: Speicherverbrauch, Anzahl Threads und und und...

- Alex


----------

