title: How to find out what is referencing a detached DOM tree using Chrome Dev Tools
body: <p>I'm trying to figure out exactly how to get which variable is referencing something in a detached DOM tree.  I've isolated the problem down to two simple views, and I'm trying to use Chrome Dev Tools (in the comparison view) to find out what is referencing the detached nodes.  I've attached an image of dev tools... </p>
  
  <p><img src="https://i.stack.imgur.com/AMOtP.png" alt="Chrome dev tools snapshot"></p>
  
  <p>The bottom part of dev tools shows that <code>el</code> of <code>HomeView</code> has created a div that became detached.  But I'm not sure where to go from there.</p>
  
  <p>I've read through a bunch of stack overflow posts and blog posts on pinpointing memory leaks, but I still can't figure this one out.  I know that Backbone is especially likely to cause memory leaks, so I've implemented the "zombie-killing" techniques, but the memory leak is still there.  Here are my views:</p>
  
  <p>Help View</p>
  
  <pre><code>    // Generated by CoffeeScript 1.6.3
      (function() {
        var __hasProp = {}.hasOwnProperty,
          __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
  
        define(['jquery', 'jquerymobile', 'underscore', 'backbone'], function($, Mobile, _, Backbone) {
          var HelpView, _ref;
          return HelpView = (function(_super) {
            __extends(HelpView, _super);
  
            function HelpView() {
              _ref = HelpView.__super__.constructor.apply(this, arguments);
              return _ref;
            }
  
            HelpView.prototype.initialize = function() {
              return _.bindAll(this, "render", "jqdisplay", "close");
            };
  
            HelpView.prototype.render = function() {
              $(this.el).html("Help View");
              return this;
            };
  
            HelpView.prototype.jqdisplay = function() {};
  
            HelpView.prototype.close = function() {
              console.log('THIS', this);
              console.log($(this.el)[0].parentNode);
              $(this.el)[0].parentNode.removeChild($(this.el)[0]);
              this.undelegateEvents();
              $(this.el).removeData().unbind();
              this.remove();
              this.unbind();
              Backbone.View.prototype.remove.call(this);
              return delete this;
            };
  
            return HelpView;
  
          })(Backbone.View);
        });
  
      }).call(this);
  </code></pre>
  
  <p>Home View</p>
  
  <pre><code>    // Generated by CoffeeScript 1.6.3
      (function() {
        var __hasProp = {}.hasOwnProperty,
          __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
  
        define(['jquery', 'jquerymobile', 'underscore', 'backbone'], function($, Mobile, _, Backbone) {
          var HomeView, _ref;
          return HomeView = (function(_super) {
            __extends(HomeView, _super);
  
            function HomeView() {
              _ref = HomeView.__super__.constructor.apply(this, arguments);
              return _ref;
            }
  
            HomeView.prototype.initialize = function() {
              return _.bindAll(this, "render", "jqdisplay", "close");
            };
  
            HomeView.prototype.render = function() {
              $(this.el).html("Home View");
              return this;
            };
  
            HomeView.prototype.jqdisplay = function() {};
  
            HomeView.prototype.close = function() {
              console.log('THIS', this);
              console.log($(this.el)[0].parentNode);
              $(this.el)[0].parentNode.removeChild($(this.el)[0]);
              this.undelegateEvents();
              $(this.el).removeData().unbind();
              this.remove();
              this.unbind();
              Backbone.View.prototype.remove.call(this);
              return delete this;
            };
  
            return HomeView;
  
          })(Backbone.View);
        });
  
      }).call(this);
  </code></pre>
  
  <p>...and then I call the "close" method of each view in a method in my router...</p>
  
  <pre><code>  MyRouter.prototype.showView = function(view) {
      console.log('THIS', this);
      console.log("next view", view);
      console.log(this.currentView);
      if (this.currentView) {
        console.log('closing the current view...', this.currentView);
        console.log('starting', $('[data-role="content"]').html());
        this.currentView.close();
        delete this.currentView;
        console.log('remaining', $('[data-role="content"]').html());
        console.log('should be empty', this.currentView);
      }
      this.currentView = view;
      this.currentView.render();
      $('[data-role="content"]').html(this.currentView.el);
      if (this.currentView.jqdisplay) {
        return this.currentView.jqdisplay();
      }
    };
  </code></pre>
  
  <p>A live demo of the leak is here: <a href="http://bit.ly/15xPrW7" rel="noreferrer">http://bit.ly/15xPrW7</a>.
  The leak-triggering behavior is using the menu to navigate between the two pages.</p>
  
  <p>Any help would be appreciated!  Thank you!</p>