angularjs d3.js memory-leaks nvd3.js

Cómo evitar fugas de memoria usando angularjs-nvd3-directives



d3.js memory-leaks (3)

Estoy trabajando en una aplicación angularjs usando angularjs-nvd3-directives para representar gráficos.

Después de un control con Chrome Developer Tools, detecté algunas pérdidas de memoria vinculadas a los gráficos. Cuando el usuario navega a través de diferentes vistas que contienen gráficos, la memoria nunca se libera por completo.

Ya estoy haciendo una limpieza en los controladores de gráficos:

$scope.$on(''$destroy'', function() { d3.select( ''#exampleId'' ).remove(); d3.select( ''#exampleId2'' ).remove(); ... });

Y en el evento routeChange:

myApp.run(function($rootScope, $templateCache) { //try to clear unused objects to avoid huge memory usage $rootScope.$on(''$routeChangeStart'', function(event, next, current) { if (typeof(current) !== ''undefined''){ //destroy all d3 svg graph d3.selectAll(''svg'').remove(); nv.charts = {}; nv.graphs = []; nv.logs = {}; } }); });

Cuando elimino los gráficos de mi aplicación, el uso de la memoria siempre vuelve al valor inicial.

Con el gráfico: Sin

¿Hay alguna otra forma de liberar la memoria generada por esos gráficos?

jsfiddle para demostrar el problema.


Es posible que olvide eliminar los oyentes de cambio de tamaño de la ventana.

angularApp.run(function($rootScope) { $rootScope.$on(''$routeChangeStart'', function(event, next, current) { if (typeof(current) !== ''undefined''){ //destroy d3 stuff window.nv.charts = {}; window.nv.graphs = []; window.nv.logs = {}; // and remove listeers for onresize. window.onresize = null; } }); });

También puedes intentar eliminar todo el elemento svg, pero no parece ser la mejor manera.


Hay un problema similar en github: https://github.com/cmaurer/angularjs-nvd3-directives/issues/193

Como expliqué, lo siguiente funcionó mejor:

$rootScope.$on(''$stateChangeStart'', function (event, toState, toParams, fromState, fromParams) { angular.element(document.body.querySelectorAll(''.nvd3'')).remove();

Esto resuelve las fugas de memoria SVG. Pero aún hay algunas pérdidas de memoria en el lado de los datos (Array).


Recomiendo que mueva su gráfico a sus propias directivas que contendrán las directivas nvd3 en sus plantillas y escuchará en cada directiva el alcance.

$destroy también destruye el elemento en este evento.

Los controladores deben recuperar los datos y asignarlos a la directiva.

Es posible que desee escuchar el $routeChangeStart en la directiva, por lo que la limpieza se encapsulará en la parte que utiliza los datos. De esta forma evitará el código duplicado.

Utilizo estas técnicas para limpiar mis directivas que usan modales, por lo que no tengo duplicados oyentes o identificadores de eventos.