2012-05-30 6 views
5

Supponiamo di avere un componente il cui compito è, tra le altre cose, di creare qualche nodo DOM (ad esempio con jQuery):Evitare con gli oggetti che creano e rimuovono DOM con jQuery

function PageFiller() { 
} 
PageFiller.prototype.fillPage = function() { 
    this.dom = $("<div/>", { 
    "class" : "hello", 
    text : "Hello world" 
    }); 
    $("body").append(this.dom); 
} 

Supponiamo che un altro componente usa questo per riempire il DOM, senza mantenere un riferimento al "PageFiller"

function Main() { 
} 
Main.prototype.start = function() { 
    var filler = new PageFiller(); 
    filler.fillPage(); 
}; 
var main = new Main() 
main.start(); 

Non supporre che subito dopo che (nello stesso ambito), qualcuno cancella brutalmente il DOM:

$(".hello").remove(); 

Qual è il layout di memoria in una situazione del genere? Ho perso la memoria con l'istanza di PageFiller?

Sono un po 'incerto a quale punto l'istanza di PageFiller otterrebbe garbage collection (se mai dovesse accadere), poiché contiene un riferimento a un oggetto jquery che rappresenta una parte del DOM che non esiste più? O ha nulla a che fare con il DOM, dal momento che da quanto ho capito le effettivi oggetti DOM vivere in un mucchio di diverso rispetto alle normali variabili JS (se non mi sbaglio qui ..)

AGGIORNAMENTO: Una variante della cosa sarebbe se il riferimento al PageFiller è stato mantenuto dall'oggetto principale:

Main.prototype.start = function() { 
    this.filler = new PageFiller(); 
    filler.fillPage(); 
} 

In questa situazione, l'oggetto principale ha un riferimento all'oggetto PageFiller, che a sua volta contiene un riferimento a un oggetto JQ; dopo la 'rimozione', l'oggetto JQ esiste ancora in memoria, ma punta a nodi DOM inesistenti, giusto?

Sono corretto dire che nell'esempio originale, non appena main.start() è terminato:

  • nessun oggetto contiene un riferimento all'oggetto PageFiller, quindi diventa rifiuti raccolti, e la L'oggetto pageFiller.dom non viene referenziato da nessuno, quindi viene raccolto anche garbage collection?
  • gli elementi DOM effettive, ovviamente, esiste ancora in memoria, ma in un mucchio separato che io in realtà non devono preoccuparsi di

ALTRE CASE:

Questa volta una piccola variazione, con i gestori di eventi a complicare le cose:

PageFiller.prototype.fillPage = function() { 
    var self = this; 
    this.dom = ... // as usual 
    this.dom.click(function() { 
    alert("Just clicked on dom generated by " + self); 
    }); 
} 

Questa volta, solo lasciando l'istanza PageFiller corto di portata non poteva essere sufficiente per avere la memoria recuperata, in quanto fa riferimento alla chiusura utilizzato nel gestore di click. Ho fatto trapelare la memoria qui? O posso fidarmi della chiamata $ (""). Remove() per uccidere il riferimento alla chiusura, quindi uccidere l'ultimo riferimento al PageFiller? E le cose si comporterebbero in modo diverso se rimuovessi l'elemento senza jquery (con l'API DOM nativa?)

Probabilmente tutto funziona come spero, ma sto solo cercando di convincermi che nessun ricordo può perdere da questo schema .

Grazie.

+0

Ci sono purtroppo pochissime buone domande contrassegnate da jQuery. Sono orgoglioso di dare a questo il mio +1. –

+0

I browser usano (variazioni di) GC Mark-and-sweep, quindi quando siamo fuori dal contesto dell'istanza del filler di partenza verrà contrassegnato per la raccolta, ma il div resterà nel DOM. – jasssonpet

+0

@Truth sei il benvenuto. – phtrivier

risposta

1

aggiornamento

Rimozione del filler.dom volta main.start() ha terminato diminuirà la refcount per i nodi sono in possesso a, perché non possiede i nodi (cioè debole di proprietà).

Quando i nodi effettivi vengono rimossi quando si chiama $().remove(), il numero di riferimento viene nuovamente ridotto a zero e può essere eliminato.

Quindi, AFAICT non dovresti avere nulla di cui preoccuparti.

+0

Quindi chi è il "proprietario del nodo" in questa situazione? C'è un modo per accedere ai refcounts (con gli strumenti di sviluppo Firebug o Chrome?) Inoltre ho aggiornato la domanda con pochi altri casi, solo per essere sicura. – phtrivier

+0

@phtrivier quando il 'filler' viene contrassegnato per GC, solo il DOM" possiede "il nodo. Sfortunatamente, non è possibile vedere il numero di riferimento da soli; vedi anche: http://stackoverflow.com/questions/2937120/how-to-get-javascript-object-references-or-reference-count –

Problemi correlati