2010-06-20 9 views
7

Esta es la forma que tengo cosas de configuración:¿Cuál es la mejor manera de liberar la memoria del navegador cuando se trabaja con grandes arreglos en javascript?

  • container.html
  • database1.js (contiene gran variedad llamada database1)
  • database2.js (contiene gran variedad llamada database2)

He aquí una muestra de la matriz (acortado de 6000 + filas a 2):

var database1=[[ 
    "2010-01-03 07:45","2010-01-03 11:00","534","A","","","","","Installed washing machine","0","1","1","Indeed","",""],[ 
    "2010-03-20 15:00","2010-03-20 16:00","571","F","","","","","Installed oven","0","5","1","Indeed","",""],[ 
    etc,etc,etc...]]; 

Cuando anexo database1.js a la cabecera del contenedor, la memoria utilizada para IE en Windows salta de 7,7MB a 21,9MB. Esto está bien, ahora puedo recorrer el conjunto llamado base de datos1 (la primera fila y la columna están en la base de datos 1 [0] [0]).

El problema es que tengo que volver a anexar el archivo de la base de datos de vez en cuando y al hacerlo, el uso de la memoria aumenta (pensé que la matriz de la base de datos se sobrescribiría).

Así que la primera re-append empuja el uso de memoria en el IE hasta 30,4MB pero luego sigue aumentando en cada re-append: 30,4MB> 33,9MB> 39,5MB> 42,1MB etc.

Para evitar que esto ocurra, borro cada elemento de la matriz antes de volver a agregar el archivo de la base de datos.

for (var i=0, il=database1.length; i<il; i++){ 
delete database1[i]; 
} 
//append database1.js to head code here 

Esto ayuda a. El uso de la memoria no disminuye a los 7,7 MB iniciales, pero sin embargo disminuye de 21,9 MB a 14,1 MB. La próxima reaplicación aumenta la memoria a 25,9 MB (borrado con el ciclo: 18,8 MB). La próxima reanexión aumenta la memoria a 29,3 MB (borrado con el bucle: 24,5 MB).

Me alegro de que el uso de la memoria no esté aumentando tan rápido, pero quizás esto se pueda optimizar aún más. Lamentablemente, volver a cargar la página HTML no es una opción.

+0

(su cuenta de stackoverflow se debe arreglar ahora) –

Respuesta

6

La administración de la memoria en JavaScript es asistida por el recolector de elementos no utilizados, una característica del lenguaje que periódicamente desasigna la memoria que ya no es necesaria.

El operador delete denota esencialmente un área de memoria que ya no se necesita. La memoria se desasignará cuando se ejecute el recolector de basura.

La recolección de basura no es predecible - delete $var o $var = null permitirá que el recolector de basura para desasignar la memoria finalmente. Esto puede no ser instantáneo. Esta es la razón por la que el uso de la memoria no está subiendo tan rápido como cabría esperar, y esta es la razón por la que delete $var no reduce el uso de la memoria tan rápido como cabría esperar.

IE sí presenta un medio para forzar el recolector de basura para funcionar:

if (typeof(CollectGarbage) == "function") { 
    CollectGarbage(); 
} 

Su script puede reducirse, mientras que esto está ocurriendo, sobre todo si hay una gran cantidad de memoria para cancelar la asignación.

Lo mejor es evitar forzar la recolección de basura: deje que el recolector de basura se ejecute en el punto que considere más apropiado. CollectGarbage() tampoco está documentado; el comportamiento puede cambiar o la función puede eliminarse en cualquier momento.

En resumen:

  • su uso de delete database1[i] es el mejor que puede hacer
  • esto va a cancelar la asignación de memoria finalmente
  • uso de la memoria volverá al nivel esperado finalmente
  • puede forzar la recolección de basura en IE, pero este proceso eventualmente ocurrirá por su cuenta
+0

Dos comentarios: 1. Como 'typeof' es un operador, no tiene que poner llaves alrededor del operando. 2. Recuerde que no puede 'eliminar' [variables globales] (http://perfectionkills.com/understanding-delete/#property_attributes):" Cuando las variables y funciones declaradas se convierten en propiedades de un objeto Variable - cualquiera de los objetos de Activación (para Código de función) u objeto global (para código global), estas propiedades ** se crean con el atributo DontDelete **. "Pero supongo que el OP no funciona con variables globales en este caso (ya que la memoria está realmente liberada). –

+0

De una respuesta de @Ben: "Saludos Jon por esa gran explicación". –

+0

Estoy trabajando con variables globales, y el uso de eliminar no libera memoria en mi caso. Pero tal vez eliminar no elimina, ¿pero borra el artículo? Reemplacé [code] delete database1 [i] [/ code] con [code] database1 [i] = "" [/ code] y esto dio el mismo resultado. – Ben

Cuestiones relacionadas