2009-03-20 15 views
6

Possiedo un'interessante applicazione Flex & Papervision3D che crea e distrugge continuamente gli oggetti. Carica e scarica anche i file di risorse SWF. Mentre è in esecuzione, il file SWF consuma lentamente la memoria fino a 2 GB quando gracchia il lettore. Ovviamente sono abbastanza sicuro di lasciare andare il riferimento a istanze che non voglio più con aspettativa che il GC farà il suo lavoro. Ma sto avendo un pò di tempo per capire dove si trova il problema.Debug di perdite di memoria FLEX/AS3

Ho provato a utilizzare il profiler e le sue opzioni per l'acquisizione di istantanee di memoria, ecc., Ma il mio problema rimane evasivo. Penso che ci siano problemi noti anche con il debug di Flash Player? Ma non provo gioia nemmeno con la versione di rilascio.

Come si fa a rintracciare i problemi di perdita di memoria utilizzando FLEX/AS3? Quali sono alcune strategie, trucchi o strumenti che hai utilizzato per individuare i consumi

risposta

3

ci siamo imbattuti in qualcosa che spiega come utilizzare Flex Profiler in Flex Builder ed è stato un grande aiuto per me nel debugging perdite di memoria. Suggerirei sicuramente di provarlo. È molto facile da usare. Alcune cose che ho trovato durante il profiling delle mie applicazioni:

Evitare l'uso di raccolte (almeno LARGE collections) come proprietà di Value Objects. Ho avuto diversi tipi di classi di oggetti di valore nella mia applicazione Cairngorm, e ciascuno aveva una proprietà "bambini" che era uno ArrayCollection, ed era usato per il filtraggio. Durante la creazione di profili, ho scoperto che questi erano uno dei miei più grandi mangiatori di memoria, quindi ho cambiato la mia applicazione per memorizzare invece "parentId" come int e utilizzarla per filtrare. La memoria utilizzata è stata tagliata drasticamente. Qualcosa di simile a questo:

Vecchio modo:

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 
} 

Vorrei anche suggerire la rimozione di listener di eventi quando essi non sono più necessari.

2

Se la perdita di memoria aumenta in modo esponenziale, probabilmente significa che GC non riesce a fare il suo lavoro. Dai un'occhiata al tuo codice e vedi dove puoi ridurre il numero di riferimenti dei tuoi oggetti (impostandoli su null). Rendi deboli i gestori di eventi. E ri-profilo.

4

Io di solito implemento un metodo di pulizia in ogni classe che faccio (dato che AS non ha distruttori). Il problema principale che ho notato con il GC è con gli ascoltatori di eventi. Oltre a ciò che dice dirkently, cerca anche di evitare le funzioni anonime del listener (dato che non puoi rimuoverle esplicitamente). Qui ci sono alcuni link si possono trovare utili:

+0

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

3

a causa di problemi come questo ho sviluppato una libreria open source che aiuta a monitorare tutti gli eventi in esecuzione in un dato momento. è davvero facile da implementare e ho rielaborato i progetti in 10-15 minuti convertendoli per utilizzare EventController che ho sviluppato.

fondamentalmente per il vostro scenario vorrei correre attraverso tutti gli eventi e sostituirli da: obj.addEventListener (...);

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

il resto è lo stesso che ciò che farebbe registrare l'evento e renderlo pazzesco facile vedere tutti i tuoi eventi in qualsiasi momento tu voglia utilizzando EC.log();

tutti i dettagli e la documentazione sono sul mio sito mi piacerebbe sapere se questo ti aiuta e se si inizia a lavorare con esso. se avete qualche feedback buono o cattivo, non esitate a postarlo e vorrei guardarlo!

il sito è: http://fla.as/ec/