¿Cómo destruir un objeto JavaScript?

81

Recientemente, encontré una de mis aplicaciones que consume demasiada memoria y aumenta en 10 MB / seg.

Entonces, me gusta saber la mejor manera de destruir objetos y variables de JavaScript para que el consumo de memoria permanezca bajo y mi FF no se pueda destruir.

Estoy llamando a dos de mi JavaScript en cada intervalo de 8 segundos sin volver a cargar la página.

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

¿Cómo puedo ver qué variable causa la sobrecarga de memoria y el método para detener la ejecución de ese proceso?

Amit Shah
fuente
1
¿Ha considerado aislar partes de sus códigos mediante cierres?
YS.
1
¿Has probado algo? ¿Te gusta usar obj = null?
Florian Margaine
A) ¿Qué hace show_topology? --- B) ¿Alguna vez está limpiando las cosas que agrega #td_123? --- C) ¿Hay una versión en vivo de esto en alguna parte?
Deestan

Respuestas:

93

Puede poner todo su código en un espacio de nombres como este:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

El uso de la deletepalabra clave eliminará la referencia a la propiedad, pero en el nivel bajo, el recolector de basura (GC) de JavaScript obtendrá más información sobre qué objetos se recuperarán.

También puede usar las herramientas de desarrollo de Chrome para obtener un perfil de memoria de su aplicación y qué objetos de su aplicación deben reducirse.

Yochai Akoka
fuente
12
Presione F12 para obtener las herramientas de desarrollo. Vaya a la pestaña Perfil y haga clic en Iniciar para iniciar el perfil. Puede crear perfiles en JS CPU, CSS Selector y puede tomar la instantánea de Heap.
Sarath
3
o en el último Chrome, escriba la palabra rendimiento en la consola js
David Morrow
Quizás sea obvio, pero puede nombrar su espacio de nombres con algo como "g" y ahorrar mucho tiempo de escritura. Use g.curItem = ... en lugar de var curItem = ... y guarde la escritura y permita que g = undefined borre toda la asignación de memoria global.
David Spector
31

No se pueden eliminar objetos, se eliminan cuando no hay más referencias a ellos. Puede eliminar referencias con delete.

Sin embargo, si ha creado referencias circulares en sus objetos, es posible que deba desacoplar algunas cosas.

CódigoClown42
fuente
2
¿Podría agregar un ejemplo de una referencia circular que no sería detectada por el recolector de basura? ¡Pidiendo un amigo! ;)
emilhem
@emilhem, puede hacer referencia al recolector de basura y se eliminará a sí mismo y a Internet; la implosión posiblemente cree un agujero negro en el CERN. ¿Has pensado en ese ejemplo?
El Mac
28

Si bien las respuestas existentes han dado soluciones para resolver el problema y la segunda mitad de la pregunta, no brindan una respuesta al aspecto de autodescubrimiento de la primera mitad de la pregunta que está en negrita:

"¿Cómo puedo ver qué variable causa sobrecarga de memoria ...?"

Puede que no fuera tan sólido hace 3 años, pero la sección " Perfiles " de las herramientas de desarrollo de Chrome ahora es bastante poderosa y rica en funciones. El equipo de Chrome tiene un artículo perspicaz sobre su uso y, por lo tanto, también sobre cómo funciona la recolección de basura (GC) en javascript, que es el núcleo de esta pregunta.

Dado que deletees básicamente la raíz de la respuesta actualmente aceptada por Yochai Akoka, es importante recordar lo que hace la eliminación. Es irrelevante si no se combina con los conceptos de cómo funciona GC en las siguientes dos respuestas: si hay una referencia existente a un objeto, no se limpia. Las respuestas son más correctas, pero probablemente no tan apreciadas porque requieren más reflexión que simplemente escribir 'eliminar'. Sí, una posible solución puede ser usar delete, pero no importará si hay otra referencia a la pérdida de memoria.

Otra respuesta menciona apropiadamente referencias circulares y la documentación del equipo de Chrome puede proporcionar mucha más claridad, así como las herramientas para verificar la causa.

Como deletese mencionó aquí, también puede ser útil proporcionar el recurso Understanding Delete . Aunque no entra en ninguna de las soluciones reales que están realmente relacionadas con el recolector de basura de JavaScript.

Shwaydogg
fuente
9

Estructura tu código para que todos tus objetos temporales estén ubicados dentro de cierres en lugar de espacios de nombres globales / propiedades de objetos globales y salgan del alcance cuando hayas terminado con ellos. GC se encargará del resto.

Oleg V. Volkov
fuente
1

Me enfrentaba a un problema como este y tenía la idea de simplemente cambiar el HTML interno de los hijos del objeto problemático.

adiv.innerHTML = "<div...> the original html that js uses </div>";

Parece sucio, pero me salvó la vida, ¡ya que funciona!

Sergio Abreu
fuente