32

Tengo una pregunta con respecto a la recolección de basura en google chrome (Versión 20.0.1132.47, Ubuntu 11.04 64bit).Las instancias a las que hace referencia 'bound_this' solo no son basura recolectada

Mientras comparaba los volcados de pila y comprobaba si había fugas de memoria, descubrí algunas instancias que nunca se limpian. Normalmente, este comportamiento puede ser rastreado a un programador de errores, pero en este caso estoy bastante desorientado ..

Tome un vistazo a la siguiente pantalla

La instancia está referenciado Screenshot of heap-dump showing an instance (child) referenced only by 'bound_this'

'niño @ 610739' solo por 'bound_this' instancias que pertenecen a las funciones de la instancia-hija misma. Por lo tanto, a mi entender, la instancia hija debe ser recolectada como basura, ya que la única otra referencia que lo mantiene es la instancia hija misma (a través de las funciones 'bound_this').

estoy usando la función underscore.js' 'bindAll' utilidad (underscore.js#bindAll) que se asigna a la función 'native_bind' de cromo (ECMA Script wiki on bound_this)

Me estoy perdiendo algo obvio aquí y si es así, ¿podría alguien explicar ¿Qué mantiene estas instancias con vida?

ACTUALIZACIÓN:
Mientras tanto Probé la misma aplicación en chrominium (18.0.1025.168 (Build para desarrolladores de Linux 134367) Ubuntu 11.10), que no muestra estos casos colgando ..

ACTUALIZACIÓN 2:
Siguiendo La sugerencia de Esaili para proporcionar un fragmento de jsfiddle, creé uno (http://jsfiddle.net/8gSTR/1/) que imita lo que básicamente estoy haciendo. La ejecución de este violín desafortunadamente no muestra la mala conducta que estoy experimentando en mi aplicación. Un montón-dump tomada mientras 'A'-casos aún se hace referencia parece algo similar, aunque a pesar de la referencia de la matriz window.o que mantiene vivos los casos: Heap-dump taken during execution of jsfiddle mentioned above

como referencia tal no se encuentra en mi caso (captura de pantalla 1) No sé qué impide que Chrome libere estas instancias ...

ACTUALIZACIÓN 3:
Se han seguido los consejos para habilitar las propiedades ocultas. El resultado (con una de las ramas expandidas) se puede ver en la siguiente captura de pantalla, pero no me lleva más lejos. Heap-dump with hidden properties enabled

+0

No lo veo aquí http://jsfiddle.net/uGX22/3/. Inicialmente están allí (Heap teniendo 17.32mb con 60000 cierres), espero unos minutos y tomo una nueva instantánea y el montón vuelve a 6mb y los cierres desaparecen. ¿Puedes modificar mi jsfiddle para reproducir esto? – Esailija

+0

¿Podría mostrarnos el código con el que creó esta situación? Realmente no lo entiendo de la captura de pantalla del depurador. – Bergi

+0

Intentaré crear un pequeño fragmento para reproducir el problema. El código con el que creé la situación es parte de un SPA bastante grande, por lo que no es tan fácil de extraer. –

Respuesta

3

Sus sospechas de que esto no es una pérdida de memoria real, sino la rareza con Chrome es correcta.

Recientemente me encontré con el mismo problema. IE11 no mostrará this.func = _.bind (this.func, this) como una pérdida de memoria mientras que Chrome lo hará, incluso después de presionar el botón de recolección de basura 100 veces.

Lo mostrará incluso después de ejecutar cromo con el sinsentido jsflag y exponer el recolector de basura subyacente y llamar a gc 100 veces.

Una manera fácil de demostrar que en realidad no es una fuga en Chrome es hacer que un problema menor sea un problema importante con el navegador y forzar al motor a tomar medidas.

En la instancia que tiene la función de límite asignado asignar una nueva propiedad como esta:

target.WhyAmILeaking = new Array (200000000) .join ("YOURNOT");

Realice la técnica de captura de tres instantáneas con cromo y verá que la cadena está presente en el monopolio del reloj en alrededor de 214mb. Haga de nuevo la acción constructiva (la segunda instantánea) y verá que el montón va a 423 mb o se queda en 214 mb. Si se queda, terminaste ya que demostraste que se han recogido los 214 mb originales. Si no se queda, realiza tu acción destructiva (tercera instantánea) y volverá a los 214 mb también probando que el original fue recolectado.

Si solo se queda en 423 mb, señor o señora tiene una filtración.

Ah, y otro grupo de pobres almas que corrían a través de la misma situación: https://github.com/jashkenas/backbone/issues/2269#issuecomment-13610969

TL; DR; use IE 11 para detectar fugas.

1

he hecho referencia esto en EcmaScript, este término "ligado este" con la clase,

métodos de clase han “unido este”, donde esta en el cuerpo del método siempre está obligado a la instancia de clase de la cual la se extrajo el método, independientemente de qué este parámetro se pasa realmente al método (se ignora este parámetro para el método).

Ahora aquí en su ejemplo no hay un script de ejemplo dado por lo que no puede ser específico a la pregunta,

tengo que decir que si esto no se escapa ..

luego con lo que cada vez el objeto, la clase La secuencia de comandos está limitada, no llamará a basura hasta que exista la clase/objeto, ya que esta función está limitada por el mismo objeto. Se recolectará la basura solo después de que finalice el alcance de su padre (el objeto/clase con el cual está limitado).

Ahora bien, si la referencia circular cuando la tarea termine terminará, >> esto funciona como concepto de recursión (tenga en cuenta el concepto, no lo mismo que) ... así que el final comenzará desde la última llamada .. en inverso ... la llamada más interna (última llamada) se lanzará primero ... y así sucesivamente

El código debe tener errores, ya que no deben vincularse y definir la función y la reutilización cada vez ... pero si son vinculantes, entonces también debería funcionar bien y no debería tener fugas hasta que la huella salga del límite de memoria del grupo de memoria.

espero que esto explicará ..

1

¿Está provocando una "GC forzada" por medio de las herramientas de desarrollo? Si ese es el caso y los objetos persisten entonces la investigación anterior es valiosa.

Si no está activando un GC a través de las herramientas de desarrollador, recuerde que la forma en que funciona el motor de GC es bastante complicada y tiene el concepto de colección generacional (utilizando dos generaciones).

http://www.html5rocks.com/en/tutorials/memory/effectivemanagement/#toc-v8-gc

Podría ser simplemente que no ha alcanzado el umbral requerido para desencadenar una generación joven de GC, o que los objetos han sido tenured a la vieja generación, sino que un GC vieja generación nunca fue disparada.

Desafortunadamente las herramientas de desarrollador no parecen mostrar qué generación fue GC'd.

Cuestiones relacionadas