2011-06-09 23 views
15

Si tengo una función como estaJavascript recolección de basura función anónima

function do(callback) { 
    //do stuff 
    callback(); 
} 

y luego me pase en una función anónima:

do(function() { //do something else }); 

hace que la función anónima Alguna vez se recoge durante la vida útil del ¿página? Si no, ¿cómo puedo ponerlo a disposición para GC?

¿Tengo que hacer esto?

var h = function() { //do something }; 
do(h); 
delete h; 

¿Tengo que preocuparme por esto? Estoy construyendo una aplicación web que tiene una larga vida útil, hace que muchas llamadas ajax conserven objetos por un tiempo y realmente no requieren una actualización de página para navegar. Así que estoy tratando de averiguar si podría caer en un monstruo de fuga de memoria.

+0

para mí, que tienden a obtener la mayor cantidad de pérdidas de memoria de no quitar detectores de eventos a objetos que pensé que había eliminado. Hay otros mensajes de fuga de memoria relacionados con JS por aquí http://stackoverflow.com/questions/5028479/finding-memory-leaks-in-javascript-using-firebug También es posible que desee ver aquí http://stackoverflow.com/questions/864516/what-is-javascript-garbage-collection – mrk

Respuesta

9

La única referencia a la función anónima es el argumento de función, y que desaparece cuando la función finaliza, por lo que su devolución de llamada estará disponible para la recolección de elementos no utilizados después de eso. Excepto cuando otra cosa se pone una referencia a él, lo que puede suceder fácilmente con cierres:

function doo(callback) { 
    $.get(url, function() { 
     // callback is visible here! 
    }); 
    callback(); 
} 
doo(function() { /* do something else */ }); 

callback (junto con todo el alcance creado por llamar doo) debe permanecer en la memoria, ya que la función interna puede hacer referencia a ella a través el cierre; solo puede ser basura recolectada cuando la función interna es basura recolectada, y dado que esa función es una propiedad del objeto jqXHR, ese objeto debe ser basura recolectada antes de eso, y quién sabe cuándo sucederá ...

actualización puede evitar cierres innecesarios al no definir sus funciones dentro de otras funciones:

var func = function() { 
    // callback is not visible here 
} 
function doo(callback) { 
    $.get(url, func); 
    callback(); 
} 
doo(function() { /* do something else */ }); 
+0

si quisiera hacer esto en la función 'doo' var' var g = $; g.get ... '¿eso haría que la devolución de llamada sea coleccionable? o ¿qué podría hacer para que tu ejemplo sea coleccionable? – Jose

+0

@Jose: hacer referencia a '$' con otro nombre no sirve de nada. Actualicé mi respuesta para mostrar cómo se pueden evitar los cierres.Por supuesto, si siempre puedes reutilizar los mismos argumentos en tus llamadas a 'doo' en lugar de crear una función anónima cada vez, esa es una forma más sencilla de resolver el problema. – Tgr

+0

Creo que te refieres a "var func = function() ..." no "var fun" ... o eso o $ .get (url, func) deberían actualizarse. – Crashalot

2

Tenga cuidado con las referencias circulares, de lo contrario, el GC del navegador las limpiará. Los cierres hacen que sea realmente fácil crear una referencia circular, y que podría quedar atrapada en la memoria incluso si navegas fuera de la página que la creó. Por lo tanto, las aplicaciones web que permanecen en pantalla durante largos períodos de tiempo son especialmente vulnerables.

Consulte la sección "Fugas de memoria" aquí: https://developer.mozilla.org/en/A_re-introduction_to_JavaScript.

He diseñado bastantes aplicaciones web de página estática. He encontrado que incluso cuando no tiene tiene para limpiar objetos y controladores de eventos (es decir, está seguro de que no hay referencias circulares), no puede doler. Por lo general, solo agrega un par de líneas adicionales de código, y mantiene el uso de la memoria y la eficiencia en primer plano mientras escribe su código. Esto es algo así como un cambio para los desarrolladores web porque usualmente no tenemos que pensar mucho en este tipo de cosas cuando creamos un sitio web.