# Programm beenden



## Coder21 (29. Mrz 2007)

Hallo!
Ich habe zwei Klassen. Wenn ich die erste Beende, soll die zweite gestartet werden und andersherum. Das funktioniert ganz gut, jedoch erhalte ich nach einiger Zeit einen Java-out-of-memory-Error. 
Wie kann ich nun die Klasse, die beendet werden soll so beenden, dass der Speicher wieder freigegeben wird?

Vielen Dank für euere Hilfe!
Coder21


----------



## Wildcard (29. Mrz 2007)

Da Klassen weder laufen noch sich beenden fällt mir die Antwort auf diese Frage schwer.


----------



## Coder21 (29. Mrz 2007)

Entschuldigung. Es handelt sich um Threads.


----------



## Leroy42 (29. Mrz 2007)

Hmmh! Verläßt du denn die run-Methode nachdem du den jeweiligen
anderen Thread gestartet hat?  ???:L 

Ansonsten (also eher _nicht-ansonsten_) bräuchten wir schon den Code.


----------



## Coder21 (29. Mrz 2007)

Hallo!
Ich habe hier mal ein Beispielprogramm geschrieben:

Klasse 1:

```
import javax.swing.*;
import java.awt.event.*;

public class Klasse1 extends JFrame implements Runnable,KeyListener
{
     public Klasse1()
     {
          setVisible(true);
          addKeyListener(this);
     }
	Thread th;
	public void start()
	{
		th=new Thread(this);
		th.start();
	}
	public void run()
	{
		while(true)
		{
			...
		}
	}

	public void keyPressed(KeyEvent e)
	{
		if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
		{
			th.stop();
                        new Klasse2().start();
		}
	}
	public void keyReleased(KeyEvent e)
	{
	}
	public void keyTyped(KeyEvent e)
	{
	}
}
```

Und Klasse2:

```
import javax.swing.*;
import java.awt.event.*;
public class Klasse2 extends JFrame implements Runnable,KeyListener
{
     public Klasse1()
     {
          setVisible(true);
          addKeyListener(this);
     }
	Thread th;
	public void start()
	{
		th=new Thread(this);
		th.start();
	}
	public void run()
	{
		while(true)
		{
			...
		}
	}

	public void keyPressed(KeyEvent e)
	{
		if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
		{
			th.stop();
                        new Klasse1().start();
		}
	}
	public void keyReleased(KeyEvent e)
	{
	}
	public void keyTyped(KeyEvent e)
	{
	}
}
```


Da ich noch Anfänger bin, kann es sein, dass meine Ausdrucksweise etwas falsch ist. Ich bitte dies zu entschuldigen!

Coder21


----------



## Leroy42 (29. Mrz 2007)

Klasse 1:

```
public class Klasse1 extends JFrame implements Runnable,KeyListener
{
     ...
	public void run()
	{
                        boolean ende = false;
		while(!ende)
		{
                                   try {Thread.sleep(10);} catch(InterruptedException e) {ende = true;}
			...
		}
	}
            ...


}
```


Die Methode interrupt _bittet_ den Thread nur, sich zu beenden.
Beenden muß er sich schon selbst.

Falls noch Fragen, melde dich einfach.


----------



## Leroy42 (29. Mrz 2007)

... und natürlich

```
th.interrupt();
```
anstelle von

```
th.stop()
```
benutzen.


----------



## Coder21 (29. Mrz 2007)

Danke  

Ich werd's gleich mal ausprobieren!

Coder21


----------



## Coder21 (30. Mrz 2007)

Sehr gut! Es funktioniert jetzt!

Aber wenn jetzt eine der beiden Klassen kein Thread mehr ist, dann hab ich sofort wieder eine Java - out-of-memory Exception. Woran liegt das und wie kann ich das abstellen?
Anders gefragt: Wie kann ich jeden Speicher, den die Klasse belegt, wieder freigeben?

Ich wäre euch sehr dankbar, wenn ihr mir nochmal helfen könntet!

Coder21


----------



## Coder21 (31. Mrz 2007)

Hallo!

Ich beziehe mal mein Problem auf die Praxis.
Ich habe ein Fenster, welches das Startprogramm ist. Bei einer bestimmten Benutzereingabe wird ein dieses Fenster nicht mehr angezeigt, und ein Thread, bei dem ein zweites Fenster angezeigt wird, gestartet. Wenn nun dieser Thread beendet wird (wieder durch eine bestimmte Benutzereingabe), soll das erste Fenster wieder angezeigt werden.

Ich hoffe es klingt nicht zu kompliziert.


Ich habe noch einen zweiten Ansatz versucht:
Ich habe von diesem 1. Fenster aus, den Thread mit der Methode 
	
	
	
	





```
public void run()
```
 gestartet. Wenn dieser Thread dann fertig war, wurde das 1.Fenster wider angezeigt. Allerdings konnte so das 2. Fenster keine KeyEvents abfangen. Woran liegt das?


Ich wäre froh, wenn ihr mir eins dieser Probleme lösen könntet. Wie gesagt, bin ich noch Anfänger und kenne deshalb (noch :lol: ) nicht alle Möglichkeiten zum Lösen der Probleme.

Coder21


----------



## HoaX (31. Mrz 2007)

du weißt dass man nich nen extra thread braucht um ein zweites fenster anzuzeigen?

```
public class Window1 {

...

private void showWindow2(){
 Window2 newWin = new Window2();
 
 newWin.addWindowListener(new WindowAdapter() {
   void windowClosed(WindowEvent e) {
     Window1.this.setVisible(true);
   }
 });
 
 newWin.setVisible(true);
 this.setVisible(false);
 
}

...
}
```

so in etwa - ungetestet.
wenn das fenster 2 geschlossen wird, wird automatisch fenster1 wieder sichtbar gemacht.[/code]


----------



## Coder21 (2. Apr 2007)

Hallo!

Klar weiß ich das, aber ich brauch für mein Programm einen Thread.
Das ganze funktioniert jetzt auch super!

Dennoch weiß ich nicht, wie ich den Speicher wieder freigeben kann, nachdem der Thread geschlossen wurde.
In dem Thread habe ich unter anderem ein 1000*1000 Array, welches ich danach nicht mehr brauche.
Auch wenn ich dem Array null zuweise und dann den GarbageCollector aufrufe, wird der Speicher nicht freigegeben!
Woran liegt das??? :?:


----------



## WieselAc (2. Apr 2007)

Am besten zeigst du mal deine "aufräumen" Zeilen, sonst wird es etwas schwer. 

Ein Tipp der aber häufig passend ist: Der gc() Aufruf ist wie du sicher weißt nur ein Vorschlag, der nicht zwangsläufig umgesetzt wird. Dennoch hilft es meistens den aufruf zweimal zu machen.


----------



## Coder21 (2. Apr 2007)

Hallo!
Hier meine "aufräumen" Zeilen:


```
public void ENDE()
	{
		ende=true;                        //Abbruchbedingung in der run() Methode
		Strecke=null;                     //Strecke=Array
		System.gc();                      //Garbage Collector
	        setVisible(false);
                dispose();
		th.interrupt();                     //Thread stoppen
	}
```

Ich hoffe ihr könnt mir weiterhelfen!


----------



## Leroy42 (2. Apr 2007)

```
ende=true;                        //Abbruchbedingung in der run() Methode 
Strecke=null;                     //Strecke=Array 
System.gc();
```

Du rufst den GC ja auf, bevor der Thread beendet wird.

Vorschlag: Warte erst auf das Ende des Thread (z.B. mit join())
und rufe erst dann den GC auf.


----------



## Lim_Dul (2. Apr 2007)

Der Aufruf des GC bringt aber nix, wenn es zu einer OOM-Exception kommt. Der Fehler muss dann woanders liegen.


----------

