Estoy escribiendo una aplicación web que tiene una estática exterior «shell» y una dinámica sección de contenido. El contenido dinámico de la sección tiene muchas actualizaciones a los usuarios a navegar el sistema. Cuando un nuevo bloque de contenido está cargado, puede también cargar otro archivo JavaScript. En el nombre de una buena limpieza, me quite los bloques de script de la DOM que se aplican a los viejos bloques de contenido, ya que JavaScript no es necesario.

El problema viene después, cuando me di cuenta de que aunque me han quitado el <script> elemento del DOM, el código JavaScript que fue previamente evaluado todavía está disponible para su ejecución. Que tiene sentido, por supuesto, pero estoy preocupado de que puede provocar una pérdida de memoria si los usuarios navegar a un montón de diferentes secciones.

La pregunta, entonces, se debería estar preocupado por esta situación? Si es así, ¿hay una manera de forzar al navegador a la limpieza de rancio JavaScript?

OriginalEl autor Andy | 2009-08-28

7 Comentarios

  1. 14

    <theory>Usted podría ir con un mayor enfoque orientado a objetos, y construir el modelo, de manera que cada bloque de javascript bloques vienen en sus propios objetos, con sus propios métodos. Tras la descarga, sólo tiene que establecer que el objeto a null.</theory>

    OriginalEl autor Sampson

  2. 9

    (Esto es bastante improvisada.)

    El uso de la memoria es, de hecho, es un problema que necesita para estar preocupados con en el navegador actual estado de la técnica, aunque menos que estamos hablando de un buen montón de código, no sé que código es el tamaño de la cuestión (normalmente DOM tamaño, y las sobras de los controladores de eventos).

    Puede utilizar un patrón para sus módulos cargables de que sería mucho más fácil para descargar en masa, o al menos, para que el navegador sepa puede descarga.

    Considerar:

    window.MyModule = (function() {
    
        alert('This happens the moment the module is loaded.');
    
        function MyModule() {
    
            function foo() {
                bar();
            }
    
            function bar() {
            }
    
        }
    
        return MyModule;
    })();

    Que define un cierre que contiene las funciones foo y bar, que se puede llamar el uno al otro en la forma normal. Observe que el código fuera de funciones se ejecuta inmediatamente.

    Siempre que no pase fuera de cualquier referencia a lo que está dentro de la tapa a nada fuera de sí, entonces la ventana.MyModule será la única referencia a que el cierre y su contexto de ejecución. Descargar:

    try {
        delete window.MyModule;
    }
    catch (e) {
        //Work around IE bug that doesn't allow `delete` on `window` properties
        window.MyModule = undefined;
    }

    Que dice el entorno de JavaScript que no estás usando la propiedad más, y hace que cualquier cosa a la que hace referencia disponible para la recolección de basura. Cuando y si la colección que sucede es que, obviamente, depende de la implementación.

    Nota que va a ser importante si el gancho de controladores de eventos en el módulo de desenganche de ellos antes de la descarga. Usted podría hacer que al devolver una referencia a un destructor de la función en lugar de la principal de cierre:

    window.MyModule = (function() {
    
        alert('This happens the moment the module is loaded.');
    
        function foo() {
            bar();
        }
    
        function bar() {
        }
    
        function destructor() {
            //Unhook event handlers here
        }
    
        return destructor;
    })();

    Descolgamiento es entonces:

    if (window.MyModule) {
        try {
            window.MyModule();
        }
        catch (e) {
        }
        try {
            delete window.MyModule;
        }
        catch (e) {
            //Work around IE bug that doesn't allow `delete` on `window` properties
            window.MyModule = undefined;
        }
    }

    OriginalEl autor T.J. Crowder

  3. 3

    Si guarda el evaluado código en espacios de nombres, tales como:

    var MYAPP = {
        myFunc: function(a) { ... }
    }

    «Liberar» el todo debe ser tan simple como la creación de MYPP a algún valor aleatorio, ala

    MYAPP = 1

    Esto depende de que no hay otro medio de hacer referencia a la variable, que no es trivial

    ¿Por qué no eliminar MYAPP o MYAPP = undefined?
    No sólo la variable en sí, sino también cualquiera de los cierres que se creen ser las funciones en el interior.
    Sí, supongo que me sentí que estaba implícito. Para que esto funcione, debe haber ninguna referencia ni MYAPP, ni nada dentro de ella. Y hay algunos detalles meticulosos cuando se trata de fuga de memoria, y el IE. @Dykam: No hay razón para no ir indefinido, pero he evitado eliminar, ya que no tengo mucha experiencia con él, y un «1» no debemos poner una enorme memoria de la cepa de lo que la cooperativa puede estar haciendo.

    OriginalEl autor Svend

  4. 1

    Cómo acerca de la carga de la JS en un iframe? Entonces (en teoría, nunca probado yo mismo) se puede quitar el iframe de la DOM y quitar la «memoria» es usar.

    Creo… o espero…

    OriginalEl autor elcuco

  5. 1

    Si usted está preocupado acerca de las pérdidas de memoria, a continuación, usted querrá asegurarse de que no hay controladores de eventos en el código que desea eliminar refiriéndose a la todavía existente árbol dom.

    Puede ser que usted necesita para mantener una lista de todos los controladores de eventos el código añadido, y antes de la descarga, vaya a través de y quitar los controladores de eventos.

    Nunca lo he hecho de esa manera, siempre me preocupe cuando me quite los nodos que todavía es una referencia.

    Aquí hay un buen artículo sobre javascript pérdidas de memoria:
    http://javascript.crockford.com/memory/leak.html

    OriginalEl autor James Black

  6. 0

    JavaScript intérpretes han recolectores de basura. En otras palabras, si usted no es referencia de nada, no va a ser mantener el rumbo.

    Una de las razones por las que es bueno para usar JSON con una función de devolución de llamada (JSONP).

    ejemplo, si usted respuesta HTTP para cada JS es:

    callback({status: '1', resp: [resp here..]});

    Y si callback() no crear una referencia a un objeto JSON se puede pasar como argumento, va a ser el recolector de basura después de la función completa.

    Si usted realmente necesita para hacer una referencia, entonces usted probablemente necesita que los datos de vuelta por alguna razón – de lo contrario sería/si NO se ha hecho referencia en el primer lugar.

    De los métodos mencionados para el espacio de nombres de objetos crea una referencia que se mantendrá hasta que el recuento de referencia llega a 0. En otras palabras, usted tiene que rastrear cada referencia y eliminar más tarde, lo cual puede ser difícil cuando usted tiene los cierres y las referencias de DOM en todo mentira. Sólo una referencia va a mantener el objeto en la memoria, y algunas operaciones simples pueden crear referencias sin que se percate de ello.

    OriginalEl autor bucabay

  7. 0

    Buena discusión. Aclara un montón de cosas. Tengo otra preocupación, aunque.

    Si puedo enlazar ventana.MyModule.bar (a) a un evento, ¿qué sucede si, en el caso de que accidentalmente se activa después de la ventana.MyModule se elimina? Para mí, el punto entero de namespacing y la separación de js en módulos cargados dinámicamente es para evitar el desencadenamiento de los controladores de eventos de la cruz-módulo por error.

    Por ejemplo, si yo hago (mi excusa jQuery):

    $(‘.algunos de clase’).haga clic en(la ventana.MyModule.bar);

    ¿Qué sucede si elimino la ventana.MyModule, la carga de otro módulo y haga clic en un elemento que, accidentalmente, tiene una clase llamada alguna clase?

    OriginalEl autor Miloš Rašić

Dejar respuesta

Please enter your comment!
Please enter your name here