android game - wie man spielelemente speichert, damit gc nicht feuert

8

Ich entwickle ein Android-Spiel und habe eine Frage zum Speichern der Spielelemente, ohne Garbage Collector auszulösen.

Mein Spiel benötigt eine Sammlung, in der die Spielelemente nach x- und y-Positionen gespeichert sind (alle Spielelemente haben x, y, Breite und Höhe). Die Sammlung wird dann jedes Bild aufgerufen, um die Elemente nach cameraX, cameraY, Kamerabreite und -höhe abzurufen (der Benutzer kann durch das Spiel scrollen).

Beispiel:

 function draw() {
   tmp = collection.getElements(tmp,cameraX,cameraY,cameraWidth,cameraHeight);
     for(int i = 0; i < tmp.size(); i++) {
        tmp.get(i).draw();
     } 
  }

Ich verwende derzeit die Vector-Klasse, um die Sammlungselemente darzustellen, aber der GC wird alle paar Minuten ausgelöst. Ich mache alle meine Zuweisungen im Voraus. Ich habe auch die Funktion getElements geändert, um 1 weiteren Parameter zu akzeptieren - einen temporären Vektor (im Voraus zugewiesen), der mit Elementen gefüllt und dann zurückgegeben wird.

Wie soll ich die Spielelemente speichern, damit der GC nicht ausgelöst wird (ich bevorzuge es niemals, wenn möglich)?

Ich füge der Sammlung zur Laufzeit auch Elemente hinzu. Muss ich sie auch im Voraus zuweisen?

Jernej
quelle

Antworten:

3

Ja, wenn Sie zur Laufzeit etwas zuweisen , wird der GC möglicherweise ausgelöst. Im Allgemeinen umgehen Sie dies, indem Sie einen Objektpool implementieren. Auf diese Weise können Sie alle Objekte wie Aufzählungszeichen und andere Entitäten vorab zuordnen (oder zumindest neue Instanzen zur Wiederverwendung sammeln), um das Auslösen des GC zu vermeiden.

Bearbeiten: Möglicherweise möchten Sie auch einen Speicherprofiler (wie den Eclipse Memory Analyzer ) verwenden, mit dem Sie herausfinden können, welche Routine zur Laufzeit Objekte generiert.

Joel Martinez
quelle
Wenn Sie also eine Vektorklasse verwenden, verwenden Sie MyObject []? Aber dann muss ich die Größe des Objektpools vorab zuweisen, damit ich Objekte dynamisch hinzufügen und entfernen kann ... so etwas wie MyObject [] pool = new MyObject [MAX_OBJECTS]; hast du das gemeint
Jernej
Wenn Sie neue Objektzuweisungen zu 100% vermeiden möchten, müssen Sie jede in diesem Array enthaltene Instanz zuweisen . Ich habe eine Klasse in C # für das XNA-Framework geschrieben, die eine gute Balance findet. Sie erstellt nur dann neue Instanzen, wenn im Pool keine Instanz vorhanden ist. Das Ergebnis ist, dass in den ersten Sekunden möglicherweise einige Objekte zugewiesen werden. Sobald wir jedoch die maximale Anzahl gleichzeitiger Instanzen erreicht haben, werden keine neuen Zuordnungen vorgenommen. Sollte relativ einfach in Java zu konvertieren sein: codecube.net/2010/01/xna-resource-pool
Joel Martinez
2

Ich empfehle auch, den Quellcode für Replica Island durchzulesen , der von einem Android-Ingenieur entwickelt wurde. Er verfügt über eine generische Objektpoolklasse, die für Pools benutzerdefinierter Objekte erweitert werden kann. Er verfügt außerdem über eine benutzerdefinierte Array-Klasse (mit Funktionen zum Hinzufügen / Löschen / Suchen), um zu vermeiden, dass beim Durchlaufen eines Arrays von Objekten ein Iterator verwendet werden muss.

Außerdem möchte ich erwähnen, dass das DDMS im Android SDK in Eclipse Speicherzuordnungen verfolgen kann (siehe Registerkarte Allocation Tracker im Bild).

f20k
quelle