2009-03-20 4 views
6

Ich habe eine ziemlich große Flex & Papervision3D Anwendung, die Objekte erstellt und zerstört ständig. Es lädt und entlädt auch SWF-Ressourcendateien. Während es läuft, verbraucht die SWF langsam Speicher bis etwa 2 GB, wenn sie den Player quakt. Offensichtlich bin ich ziemlich sicher, dass ich den Bezug auf Instanzen, die ich nicht mehr möchte, mit der Erwartung, dass der GC seine Arbeit machen wird, loslassen werde. Aber ich habe eine Menge Zeit damit herauszufinden, wo das Problem liegt.Debugging FLEX/AS3 Speicherlecks

Ich habe versucht, den Profiler und seine Optionen für die Aufnahme von Speicher-Snapshots usw. zu verwenden - aber mein Problem bleibt ausweichend. Ich denke, es gibt bekannte Probleme mit Debug-Flash-Player auch? Aber ich habe auch keine Freude mit der Release-Version.

Wie gehen Sie beim Aufspüren von Speicherleckproblemen mit FLEX/AS3 vor? Welche Strategien, Tricks oder Werkzeuge haben Sie verwendet, um den Verbrauch zu lokalisieren?

Antwort

3

ich über etwas gestolpert zu erklären, wie Flex Profiler in Flex Builder zu verwenden, und es war eine große Hilfe für mich bei der Fehlersuche Speicherlecks. Ich würde definitiv vorschlagen, es auszuprobieren. Es ist sehr einfach zu bedienen. Einige Dinge, die ich bei der Profilerstellung meiner Anwendungen gefunden habe:

Vermeiden Sie die Verwendung von Sammlungen (mindestens LARGE-Sammlungen) als Eigenschaften von Wertobjekten. Ich hatte mehrere Arten von Value Object Classes in meiner Cairngorm-Anwendung, und jede hatte eine "Children" -Eigenschaft, die eine ArrayCollection war, und wurde zum Filtern verwendet. Bei der Profilerstellung stellte ich fest, dass dies einer meiner größten Speicherfresser war, also änderte ich meine Anwendung, um die "parentId" als int zu speichern und diese zum Filtern zu verwenden. Der verwendete Speicher wurde drastisch reduziert. Etwas wie folgt aus:

Alte Art und Weise:

public class Owner1 
{ 
    public var id:int; 
    public var label:String; 
    public var children:ArrayCollection; // Stores any number of Owner2 Objects 
} 

public class Owner2 
{ 
    public var id:int; 
    public var label:String; 
    public var children:ArrayCollection; // Stores any number of Owner3 Objects 
} 

public class Owner3 
{ 
    public var id:int; 
    public var label:String; 
} 

New Way:

public class Owner1 
{ 
    public var id:int; 
    public var label:String; 
} 

public class Owner2 
{ 
    public var id:int; 
    public var label:String; 
    public var parentId:int; // Refers to id of Owner1 Object 
} 

public class Owner3 
{ 
    public var id:int; 
    public var label:String; 
    public var parentId:int; // Refers to id of Owner2 Object 
} 

ich auch Ereignis-Listener entfernen würde vorschlagen, wenn sie nicht mehr benötigt werden.

2

Wenn Ihr Speicherverlust exponentiell ansteigt, bedeutet dies wahrscheinlich, dass der GC seine Aufgabe nicht erfüllt. Sehen Sie sich Ihren Code an und sehen Sie, wo Sie die Referenzanzahl Ihrer Objekte verringern können (indem Sie sie auf null setzen). Machen Sie Event-Handler schwach. Und neu profilieren.

4

Normalerweise implementiere ich eine Bereinigungsmethode in jeder Klasse, die ich mache (da AS keine Destruktoren hat). Das Hauptproblem, das ich mit dem GC bemerkt habe, ist mit Event-Listenern. Zusätzlich zu dem, was direkt gesagt wurde, versuchen Sie auch, anonyme Listener-Funktionen zu vermeiden (da Sie sie nicht explizit entfernen können). Hier sind ein paar Links können Sie nützlich:

+0

http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/arguments.html#callee – Jotham

3

wegen solcher Probleme habe ich eine Open-Source-Bibliothek entwickelt, die hilft, alle Ereignisse zu überwachen, die Sie gerade ausführen. Es ist wirklich einfach zu implementieren und ich habe Projekte in 10-15 Minuten neu berechnet, um sie in den EventController zu konvertieren, den ich entwickelt habe.

grundsätzlich für Ihr Szenario würde ich alle Ereignisse durchlaufen und sie ersetzen von: obj.addEventListener (...);

zu: EC.add (obj, ...);

Der Rest ist das gleiche was das tun würde, ist das Ereignis zu registrieren und es einfach zu machen, alle Ihre Ereignisse zu jedem beliebigen Zeitpunkt mit dem EC.log() zu sehen;

alle Details und Dokumentation sind auf meiner Website Ich würde gerne wissen, ob dies Ihnen hilft und wenn Sie anfangen, damit zu arbeiten. Wenn Sie Feedback gut oder schlecht haben, zögern Sie nicht, es zu veröffentlichen, und ich würde es untersuchen!

die Seite ist: http://fla.as/ec/