Angular утечки памяти директивы?

Я использую этот простой html файл для воспроизведения утечки памяти, которую я нашел:

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.6/angular.min.js"></script>
        <script>
            var app = angular.module('testApp', []);

            app.directive('directive1', function() {
                return {
                    template: '<div directive2></div>',
                    scope: true
                };
            });

            app.directive('directive2', function () {
                function LeakObject() {}

                function Foo() {
                    this.bar = function($scope) {
                            $scope.nottheredude;
                    };
                }

                return {
                    scope: true,
                    link: function($scope) {
                            $scope.memoryThatLeaks = new LeakObject();

                            new Foo().bar({});
                            new Foo().bar($scope);
                    }
                };
            });
        </script>
    </head>
    <body ng-app="testApp">
        <button ng-click="show = !show">Toggle</button>
        <div ng-if="show">The directive <div directive1></div></div>
        <div ng-if="!show">Nothing</div>
    </body>
</html>

У меня есть директива, которая создает только новую область и имеет другую директиву в своем шаблоне.

Другая директива делает что-то немного странное (я пытался сузить проблему до того, что вызывает утечку, и что самый короткий код, который я нашел, что воспроизводит проблему).

В моем основном html я просто переключаюсь между ничего и directive1 с помощью простого ng-if.

Обратите внимание, что directive2 также создает новый объект в $scope, называемом LeakObject. Я ожидаю, что этот объект будет собран из мусора, когда я перейду к div без ничего, так как область действия директивы должна умереть и все данные на ней с ней, но в соответствии с инструментом моментального снимка Chrome heap в режиме инкогнито, он не получает нераспределенные.

Я пытаюсь понять, почему это происходит, и почему, если я прокомментирую инструкцию в методе bar, этого не произойдет.

Шаги для воспроизведения:

  • Откройте этот файл в инкогнито
  • Откройте инструменты разработчика и перейдите в раздел Профили
  • Обновить страницу
  • Дважды нажмите Toggle (теперь вы снова видите Nothing на экране)
  • Сделайте снимок кучи
  • Напишите "утечку" в фильтре, чтобы вы могли видеть, что LeakObject все еще существует, когда он не должен действительно существовать.

Вот как это должно выглядеть:

The problem

Кто-нибудь может помочь/объяснить?

Ответы

Ответ 1

Все работает так, как ожидалось, после выполнения ваших шагов я не вижу никаких объектов утечки в снимке.

вы можете добавить следующий код в функцию ссылки, чтобы увидеть, что директива фактически уничтожает

Контроллер и директивы излучают событие непосредственно перед их уничтожением. Здесь вам предоставляется возможность снести ваши плагины и слушателей и в значительной степени выполнять сборку мусора. Подпишитесь на $scope. $On ('$ destroy',...) event

$scope.$on('$destroy',function(){
  //$scope.memoryThatLeaks = null;
  alert('!');
 });