Beseitigung von Memory-Leaks

[nocontentad]

Beseitigung von Memory-Leaks

zum
Anfang
1. Vorwort

Dieses Tutorial befasst sich mit der Beseitigung von
Memory-Leaks in euren Maps. Dadurch kann man die Performance
erheblich verbessern, was natürlich vor allem für
diejenigen unter euch interessant sein sollte, welche
Multiplayer-Maps entwickeln, besonders die mit einer
längeren Spieldauer. Allerdings wurde dieses Tutorial von
Cubasis auf www.wc3campaigns.com
veröffentlicht (Original-Tutorial)
und von mir nur ins Deutsche übersetzt.

zum
Anfang
2. Was sind Memory-Leaks

Memory Leaks (zu deutsch „Speicherlecks“) sind der
zunehmende Speicherverlust durch das Arbeiten mit Objekten.
Dies umfasst alle Objekte ohne Integer (inklusive
Einheiten-Typen, Item-Typen und Ability-IDs), Reals, Booleans
uns Strings. Wenn man ein Objekt erzeugt und man verliert die
Referenz auf diese Objekt, so ist es außerhalb der
Reichweite (dh. man kann darauf nicht mehr zugreifen), und
dadurch hat man den Verlust eines Teil des Speichers zur Folge,
welcher erst wieder freigegeben wird wenn die Map beendet
wird.

Memory-Leaks werden nur von Objekten hervorgerufen die zur
Laufzeit erzeugt werden, also dynamisch werden des Spiels. Man
muss sich also keine Gedanken um bereits im Editor plazierte
Einheiten machen, genauso wie um Regionen, Trigger und Spieler
(dies sind alles bearbeitbare Objekte). Meistens bleibt es bei
zwei Objekttypen um die man sich Gedanken machen muss:
Locations (Punkte) und Unit-Groups
(Einheitengruppen)
.

zum
Anfang
3. Auftreten

Immer dann wenn man eine Aktion erstellt und sich ein
GUI-Fenster öffnet welches die Beschriftung „Point“
trägt und etwas wählen muss, das ebenso durch eine
Variable ausgedrückt werden könnte (so zum Beispiel
Center of Region). Es wird dann ein Punkt erzeugt
welcher ein Speicherleck hervorruft, da der Punkt nirgends
gespeichert ist und somit nach dieser Aktion zwar weiterhin
besteht man allerdings keine Referenz mehr darauf hat.

In ähnlicher Weise verhält es sich mit den
Einheitengruppen – alle Aktionen des GUIs in denen man
Einheitengruppen erzeugt bzw. benötigt sorgen für ein
Memory-Leak (mit Ausnahme von last created unit
group
).Dies sind die zwei wichtigsten Faktoren, zumal
diese sehr oft benutzt werden (zB wenn man u.a. folgende
Aktionen nutzt.: Center of Region, Position of
Unit
, Pick all unit in … and do action – All
diese Aktionen erzeugen ein Speicherleck, wenn sie nicht
gespeichert und ordnungsgemäß vernichtet werden).
Player Groups (Spielergruppen) sind mit der selben Problematik
behaftet, allerdings werden diese nicht so oft benutzt. Man
kann mit ihnen aber genauso verfahren wie es später
erklärt wird.

Ebenso muss man die „temporären“ Einheiten und
Spezialeffekte bachten.

Ebenfalls eine Auswirkung, wenn auch kleiner, haben Regionen,
Timer, Timer Fenster, temporäre Dialogfenster,
temporäre Mulit- und Leaderboards, Schwebende Texte,
Sounds und Sichtbarkeits-Modifikatioren.

Aber diese Aktionen werden meistens zu selten genutzt, als dass
man sich darum kümmern müsste. Wenn der Trigger also
nur ein einziges mal, oder sehr selten, ausgelöst wird, so
braucht man sich keine Gedanken darum zu machen. Ist es
hingegen ein häufig genutzter Trigger, zB. ein
pereodisches Ereignis, oder ein Trigger mit vielen
Schleifedurchläufen sollte man darauf bedacht sein alle
Memory-Leaks in diesem Trigger zu elemenieren.

zum
Anfang
4. Beseitigung

Blizzard hat eine Reihe von Funktionen zur Verfügung
gestellt, um diese Objekte zu zerstören, allerdings wurden
diese nicht zum GUI hinzugefügt. Man hat daher zwei
Grundlegende Optionen um diese dennoch zu nutzen:

  • Custom Scipts benutzen um auf die Funktionen in JASS
    zuzugreifen
  • den WEU oder UMSWE benutzen, diese haben die
    benötigten Aktionen im GUI

Dieses Tutorial erklärt beide Vorgehensweisen.

Als erstes sollte man 1-2 Punktvariablen erzeugen, welche
TempPoint oder ähnliche Namen bekommen, ebenso sollte man
für eine Einheitengruppenvariable vorgehen. Wann immer man
nun etwas aus einem Punkt oder Einheitengruppen Fenster
auswählt muss man eine set Variable Aktion
erwarten. Man muss nun folgendes machen:

Set TempPoint = (Center of UnitSpawn <gen>)

Unit – Create 1 Footman for Player 1 (Red) at TempPoint
facing Default building facing degrees

Custom script: call RemoveLocation( udg_TempPoint )

Man kann also erkennen, dass die Center of UnitSpawn
<gen>
Aktion in ein set Variable Aktion
konvertiert wurde. Wenn man den Punkt dann benutzt hat wird er
zerstört. Um mit UMSWE das gleiche zu machen geht man wie
folgt vor:

Set TempPoint = (Center of UnitSpawn <gen>)

Unit – Create 1 Footman for Player 1 (Red) at TempPoint
facing Default building facing (270.0) degrees

Point – Remove TempPoint

Dies funktioniert in ähnlicher From für
Einheiten- und Spielergruppen (wie man sie zerstört):

Custom script: call DestroyGroup( udg_TempGroup )

Custom script: call DestroyForce( udg_TempForce ) //Force =
Player Group

UMSWE und der WEU verfügen über diese Aktionen
im GUI.

Es ist auch fast das Gleiche die Temporären Einheiten und
Spezialeffekte zu zerstören, allerdings sind diese
Aktionen im GUI verhanden. Wenn es erforderlich ist kann man
den SFX in eine Varialbe speichern (abhänging ob ein Wait
zwischen Erzeugung und Zerstörung ist, oder nicht). Dann
braucht man nur folgende Aktion:

Special Effect – Destroy TempSFX

Man sollte allerdings beachten, dass es (vor allem wenn man
Waits benutzt) zu Problemen mit den Variablen kommen kann, man
sollte also versucht sein, den Zugriff auf diese Temp-Variablen
zu kontrollieren oder mit lokalen Variablen arbeiten (worauf in
diesem Tutorial jedoch nicht eingegangen wird).

Das Entfernen von Einheiten funktioniert genau so.
Allerdings sollte man die Einheit vor dem Entfernen zuerst
töten, da sonst Probleme auftreten können, in
bestimmten Situationen (wenn die Einheit zB.: unsichtbar
gemacht wurde). Ansonsten ist das Entfernen von Einheiten
sicher, dh. es wird dabei kein zusätzliches Speicherleck
geschaffen, wie es Gerüchten zufolge heißt (nur dass
man die Einheit erst töten sollte). Für alle anderen
Typen gibt es meist eine GUI-Funktion.

Tipp:

In Trigger welche nur ein einziges
mal ausgeführt werden (Initialisierungstrigger, oder
Cinematics), kann am Ende folgende Aktion eingefügt
werden:

Custom Script: „call DestroyTrigger(GetTriggeringTrigger())“

Trigger – Destroy (Triggering Trigger) // mit WEU oderUMSWE

 

zum
Anfang
5. Schlusswort

Ich hoffe, dass euch dieses Tutorial dabei hilft die
Performance eurer Maps zu verbessern. Sollten noch Fragen offen
bleiben, so schaut einfach im Mapping-Forum vorbei.
Abschließend möchte ich noch einmal darauf
hinweisen, dass ich dieses Tutorial nur für www.warcraft-mapping.de
adaptiert habe, und die ursprüngliche Arbeit von
Cubasis stammt.

Nachtrag: In der Mappedia findet ihr weitere Informationen zu diesem Thema. Unter anderem eine Liste mit allen Destroy- und Remove-Funktionen.

zum Anfang

  • 28.07.2008 um 20:31
Guide zum Finden von Fehlern Grundlagen und Wissenswertes zum Editor

Beseitigung von Memory-Leaks

[nocontentad]

Beseitigung von Memory-Leaks

zum
Anfang
1. Vorwort

Dieses Tutorial befasst sich mit der Beseitigung von
Memory-Leaks in euren Maps. Dadurch kann man die Performance
erheblich verbessern, was natürlich vor allem für
diejenigen unter euch interessant sein sollte, welche
Multiplayer-Maps entwickeln, besonders die mit einer
längeren Spieldauer. Allerdings wurde dieses Tutorial von
Cubasis auf www.wc3campaigns.com
veröffentlicht (Original-Tutorial)
und von mir nur ins Deutsche übersetzt.

zum
Anfang
2. Was sind Memory-Leaks

Memory Leaks (zu deutsch „Speicherlecks“) sind der
zunehmende Speicherverlust durch das Arbeiten mit Objekten.
Dies umfasst alle Objekte ohne Integer (inklusive
Einheiten-Typen, Item-Typen und Ability-IDs), Reals, Booleans
uns Strings. Wenn man ein Objekt erzeugt und man verliert die
Referenz auf diese Objekt, so ist es außerhalb der
Reichweite (dh. man kann darauf nicht mehr zugreifen), und
dadurch hat man den Verlust eines Teil des Speichers zur Folge,
welcher erst wieder freigegeben wird wenn die Map beendet
wird.

Memory-Leaks werden nur von Objekten hervorgerufen die zur
Laufzeit erzeugt werden, also dynamisch werden des Spiels. Man
muss sich also keine Gedanken um bereits im Editor plazierte
Einheiten machen, genauso wie um Regionen, Trigger und Spieler
(dies sind alles bearbeitbare Objekte). Meistens bleibt es bei
zwei Objekttypen um die man sich Gedanken machen muss:
Locations (Punkte) und Unit-Groups
(Einheitengruppen)
.

zum
Anfang
3. Auftreten

Immer dann wenn man eine Aktion erstellt und sich ein
GUI-Fenster öffnet welches die Beschriftung „Point“
trägt und etwas wählen muss, das ebenso durch eine
Variable ausgedrückt werden könnte (so zum Beispiel
Center of Region). Es wird dann ein Punkt erzeugt
welcher ein Speicherleck hervorruft, da der Punkt nirgends
gespeichert ist und somit nach dieser Aktion zwar weiterhin
besteht man allerdings keine Referenz mehr darauf hat.

In ähnlicher Weise verhält es sich mit den
Einheitengruppen – alle Aktionen des GUIs in denen man
Einheitengruppen erzeugt bzw. benötigt sorgen für ein
Memory-Leak (mit Ausnahme von last created unit
group
).Dies sind die zwei wichtigsten Faktoren, zumal
diese sehr oft benutzt werden (zB wenn man u.a. folgende
Aktionen nutzt.: Center of Region, Position of
Unit
, Pick all unit in … and do action – All
diese Aktionen erzeugen ein Speicherleck, wenn sie nicht
gespeichert und ordnungsgemäß vernichtet werden).
Player Groups (Spielergruppen) sind mit der selben Problematik
behaftet, allerdings werden diese nicht so oft benutzt. Man
kann mit ihnen aber genauso verfahren wie es später
erklärt wird.

Ebenso muss man die „temporären“ Einheiten und
Spezialeffekte bachten.

Ebenfalls eine Auswirkung, wenn auch kleiner, haben Regionen,
Timer, Timer Fenster, temporäre Dialogfenster,
temporäre Mulit- und Leaderboards, Schwebende Texte,
Sounds und Sichtbarkeits-Modifikatioren.

Aber diese Aktionen werden meistens zu selten genutzt, als dass
man sich darum kümmern müsste. Wenn der Trigger also
nur ein einziges mal, oder sehr selten, ausgelöst wird, so
braucht man sich keine Gedanken darum zu machen. Ist es
hingegen ein häufig genutzter Trigger, zB. ein
pereodisches Ereignis, oder ein Trigger mit vielen
Schleifedurchläufen sollte man darauf bedacht sein alle
Memory-Leaks in diesem Trigger zu elemenieren.

zum
Anfang
4. Beseitigung

Blizzard hat eine Reihe von Funktionen zur Verfügung
gestellt, um diese Objekte zu zerstören, allerdings wurden
diese nicht zum GUI hinzugefügt. Man hat daher zwei
Grundlegende Optionen um diese dennoch zu nutzen:

  • Custom Scipts benutzen um auf die Funktionen in JASS
    zuzugreifen
  • den WEU oder UMSWE benutzen, diese haben die
    benötigten Aktionen im GUI

Dieses Tutorial erklärt beide Vorgehensweisen.

Als erstes sollte man 1-2 Punktvariablen erzeugen, welche
TempPoint oder ähnliche Namen bekommen, ebenso sollte man
für eine Einheitengruppenvariable vorgehen. Wann immer man
nun etwas aus einem Punkt oder Einheitengruppen Fenster
auswählt muss man eine set Variable Aktion
erwarten. Man muss nun folgendes machen:

Set TempPoint = (Center of UnitSpawn <gen>)

Unit – Create 1 Footman for Player 1 (Red) at TempPoint
facing Default building facing degrees

Custom script: call RemoveLocation( udg_TempPoint )

Man kann also erkennen, dass die Center of UnitSpawn
<gen>
Aktion in ein set Variable Aktion
konvertiert wurde. Wenn man den Punkt dann benutzt hat wird er
zerstört. Um mit UMSWE das gleiche zu machen geht man wie
folgt vor:

Set TempPoint = (Center of UnitSpawn <gen>)

Unit – Create 1 Footman for Player 1 (Red) at TempPoint
facing Default building facing (270.0) degrees

Point – Remove TempPoint

Dies funktioniert in ähnlicher From für
Einheiten- und Spielergruppen (wie man sie zerstört):

Custom script: call DestroyGroup( udg_TempGroup )

Custom script: call DestroyForce( udg_TempForce ) //Force =
Player Group

UMSWE und der WEU verfügen über diese Aktionen
im GUI.

Es ist auch fast das Gleiche die Temporären Einheiten und
Spezialeffekte zu zerstören, allerdings sind diese
Aktionen im GUI verhanden. Wenn es erforderlich ist kann man
den SFX in eine Varialbe speichern (abhänging ob ein Wait
zwischen Erzeugung und Zerstörung ist, oder nicht). Dann
braucht man nur folgende Aktion:

Special Effect – Destroy TempSFX

Man sollte allerdings beachten, dass es (vor allem wenn man
Waits benutzt) zu Problemen mit den Variablen kommen kann, man
sollte also versucht sein, den Zugriff auf diese Temp-Variablen
zu kontrollieren oder mit lokalen Variablen arbeiten (worauf in
diesem Tutorial jedoch nicht eingegangen wird).

Das Entfernen von Einheiten funktioniert genau so.
Allerdings sollte man die Einheit vor dem Entfernen zuerst
töten, da sonst Probleme auftreten können, in
bestimmten Situationen (wenn die Einheit zB.: unsichtbar
gemacht wurde). Ansonsten ist das Entfernen von Einheiten
sicher, dh. es wird dabei kein zusätzliches Speicherleck
geschaffen, wie es Gerüchten zufolge heißt (nur dass
man die Einheit erst töten sollte). Für alle anderen
Typen gibt es meist eine GUI-Funktion.

Tipp:

In Trigger welche nur ein einziges
mal ausgeführt werden (Initialisierungstrigger, oder
Cinematics), kann am Ende folgende Aktion eingefügt
werden:

Custom Script: „call DestroyTrigger(GetTriggeringTrigger())“

Trigger – Destroy (Triggering Trigger) // mit WEU oderUMSWE

 

zum
Anfang
5. Schlusswort

Ich hoffe, dass euch dieses Tutorial dabei hilft die
Performance eurer Maps zu verbessern. Sollten noch Fragen offen
bleiben, so schaut einfach im Mapping-Forum vorbei.
Abschließend möchte ich noch einmal darauf
hinweisen, dass ich dieses Tutorial nur für www.warcraft-mapping.de
adaptiert habe, und die ursprüngliche Arbeit von
Cubasis stammt.

Nachtrag: In der Mappedia findet ihr weitere Informationen zu diesem Thema. Unter anderem eine Liste mit allen Destroy- und Remove-Funktionen.

zum Anfang

  • 28.07.2008 um 18:31
Guide zum Finden von Fehlern Kopicon´s Melee-Map Tutorial V1.02