gekillte Spielfigur

SebOeh

Mitglied
Hallo,

Bisher habe ich nur "statische" Sachen programmiert und musste mir keine Gedanken um den GC machen. Gerade programmiere ich mal Spaßeshalber ein einfaches Spiel, sehr angelehnt an call of war.

Es geht mir hier um die grundlegende Nutzung des GC. Meine Objekte sind klein und wenige (maximal tausend mit einfachen Attributen), daher ist bei mir nicht der Speicher das Problem. Einige Objekte werden da herumstehen und nichts tun, sollen aber da bleiben; andererseits sollen einige Objekte vom Spiel verschwinden, um Fehler aller Art zu vermeiden.

Man muss sich das so vorstellen: Es gibt die militärischen Einheiten Infanterie und Panzer. Eine oder mehrere dieser Einheiten bilden Divisionen. Nur Divisionen können im Spiel Aktionen durchführen.
Es kann nun sein:
* Eine Division steht vielleicht das ganze Spiel herum, tut also nichts, darf vom GC aber nicht gelöscht werden (wird sie sowieso nicht, stelle ich mir vor)
* Eine Division killt eine andere. Die Einheiten mit Leben <0 sollten vom GC eliminiert werden, da sie sonst durch Stillstehen sich regenerieren könnten.
* Auch die Division, die keine Einheiten mehr hat, sollte auch vom GC geholt werden, damit zB keine andere feindliche Division sie angreifen kann. Wäre ja schön doof sich in eine Schlacht gegen eine leere Division zu begeben.

Der GC kann unmöglich wissen welche Divisionen noch gebraucht werden oder nicht.

Eine Möglichkeit das Problem zu umgehen, ist entweder ein Attribut "lebend oder tot" für jede Einheit oder Division zu machen. Oder man könnte eine Verwaltungstabelle einrichten.

Wie geht man sowas überhaupt an?
 
K

kneitzel

Gast
Also der GC löscht nur Instanzen, auf die es keinen Verweis mehr gibt. Damit wird nie eine Instanz gelöscht, die Du noch im Zugriff hast.

Es reicht also, wenn Du eine Instanz einfach nicht mehr referenzierst. Angenommen Du hast eine Collection mit den Einheiten. Dann reicht es, eine Einheit aus der Collection zu löschen. So da niemand sonst mehr drauf referenziert wird der GC diese Instanz irgendwann mal einsammeln und den Speicher freigeben.
 

SebOeh

Mitglied
Ah! Leuchtet mir ein!
Ich brauche nur eine Liste der noch "lebenden" Divisionen im Spiel. Oder besser: jeder Objekt der Klasse Spieler hat eine Liste von Divisionen. Eigentlich ganz einleuchtend.
Mensch, die genialsten Ideen sind die einfachsten, die wo man sich selbst doof findet wenn man sie einsieht.

Nachtrag: Und die Klasse Partie besteht u.a. aus mehreren Spielern. Wunderbar.
 

Robert Zenz

Top Contributor
Die Einheiten mit Leben <0 sollten vom GC eliminiert werden, da sie sonst durch Stillstehen sich regenerieren könnten.
Du hast (oder hattest zumindest) hier noch ein Verstaendnis Problem. Was @kneitzel gesagt hat ist vollkommen richtig, der GC "interessiert" sich nur fuer Objekte welche keine Referenzen mehr haben. Als Beispiel:

Java:
Object objectA = new Object();
Object objectB = new Object();

List<Object> list = new ArrayList<>();
list.add(objectB);

objectA = null;
objectB = null;

Nach dem dieser Code durchlaufen wurde, gibt es keine Referenz mehr auf "objectA", aber die Liste haelt noch eine Referenz auf "objectB". Also "objectA" kann tatsaechlich durch den GC endgueltig geloescht werden.

Jetzt kommt aber das Wichtige: Fuer dich als Applikations-Entwickler, ist dies komplett unzugaenglich und transparent! Ob "objectA" eingesammelt wird vom GC oder nicht, ob von "objectA" der finalizer (ja, gibt es in Java (noch)) aufgerufen wird oder nicht, ob dieser Speicher wieder freigegeben wird oder nicht, ist fuer dich komplett unnachvollziehbar. Ja, es gibt keine Referenzen mehr auf "objectA". Nein, ob der GC das Objekt wirklich einsammelt ist nicht garantiert. Es gibt die Funktion "System.gc()" um einen Lauf vom GC anzustoszen, aber selbst das ist nur ein *Vorschlag* fuer den GC, und er muss nicht. Du kannst eine Java Applikation schreiben welche 300 Tage laeuft und kein einziger GC Lauf passiert weil es nicht notwendig ist. Ob der GC ausgefuehrt wird, oder nicht, es gibt da keine Garantien fuer dich als Applikations-Entwickler.

Das bedeutet wenn du willst das ein Objekt verschwindet, musst du es aus deiner Logik entfernen, und wann dieser Speicher wieder freigegeben wird (oder halt nicht), liegt komplett auszerhalb deiner Kontrolle. Es gibt auch unterschiedliche GC Implementation welche unterschiedlich funktionieren, aber davon merkst du auf Applikationsebene auch nichts mehr.
 

temi

Top Contributor
Bisher habe ich nur "statische" Sachen programmiert und musste mir keine Gedanken um den GC machen.
Du musst dir auch weiterhin kaum Gedanken um den GC machen.

Du programmierst einfach dein Ding, der GC macht seine Arbeit, die hat aber mit deiner Spiellogik überhaupt nichts zu tun.

Wenn du Objekte (hier: Einheiten) in einer Liste hältst, die für das Spiel keine Rolle mehr spielen, dann musst du dich darum kümmern, das diese Einheiten nicht mehr kämpfen oder angegriffen werden können.
 

Ähnliche Java Themen


Oben