Suchen von JavaScript-Speicherverlusten mit Chrome


Answers

Hier ist ein Tipp zum Speicher-Profiling einer jsfiddle: Verwenden Sie die folgende URL, um Ihr jsfiddle-Ergebnis zu isolieren, entfernt es das gesamte jsfiddle-Framework und lädt nur Ihr Ergebnis.

http://jsfiddle.net/4QhR2/show/

Ich habe nie herausgefunden, wie ich mit der Timeline und dem Profiler Speicherlecks aufspüren kann, bis ich die folgende Dokumentation gelesen habe. Nachdem ich den Abschnitt mit dem Titel "Objects Allocation Tracker" gelesen hatte, konnte ich das Werkzeug "Heap-Zuordnungen aufzeichnen" verwenden und einige Detached DOM-Knoten verfolgen.

Ich habe das Problem behoben, indem ich von der jQuery-Ereignisbindung zur Backbone-Ereignisdelegierung übergegangen bin. Es ist mein Verständnis, dass neuere Versionen von Backbone automatisch die Ereignisse für Sie View.remove() wenn Sie View.remove() aufrufen. Führe einige der Demos selbst aus, sie sind mit Speicherlecks ausgestattet, damit du sie identifizieren kannst. Fühlen Sie sich frei, hier Fragen zu stellen, wenn Sie es nach dem Studium dieser Dokumentation immer noch nicht bekommen.

https://developers.google.com/chrome-developer-tools/docs/javascript-memory-profiling

Question

Ich habe einen sehr einfachen Testfall erstellt, der eine Backbone-Ansicht erstellt, einen Handler an ein Ereignis anfügt und eine benutzerdefinierte Klasse instanziiert. Ich glaube, dass durch Klicken auf die Schaltfläche "Entfernen" in diesem Beispiel alles bereinigt wird und es keine Speicherlecks mehr geben sollte.

Eine Anleitung für den Code finden Sie hier: http://jsfiddle.net/4QhR2/

// scope everything to a function
function main() {

    function MyWrapper() {
        this.element = null;
    }
    MyWrapper.prototype.set = function(elem) {
        this.element = elem;
    }
    MyWrapper.prototype.get = function() {
        return this.element;
    }

    var MyView = Backbone.View.extend({
        tagName : "div",
        id : "view",
        events : {
            "click #button" : "onButton",
        },    
        initialize : function(options) {        
            // done for demo purposes only, should be using templates
            this.html_text = "<input type='text' id='textbox' /><button id='button'>Remove</button>";        
            this.listenTo(this,"all",function(){console.log("Event: "+arguments[0]);});
        },
        render : function() {        
            this.$el.html(this.html_text);

            this.wrapper = new MyWrapper();
            this.wrapper.set(this.$("#textbox"));
            this.wrapper.get().val("placeholder");

            return this;
        },
        onButton : function() {
            // assume this gets .remove() called on subviews (if they existed)
            this.trigger("cleanup");
            this.remove();
        }
    });

    var view = new MyView();
    $("#content").append(view.render().el);
}

main();

Mir ist jedoch unklar, wie man den Profiler von Google Chrome verwenden kann, um zu überprüfen, ob dies tatsächlich der Fall ist. Es gibt eine Unmenge von Dingen, die auf dem Heap-Profiler-Snapshot auftauchen, und ich habe keine Ahnung, wie man das, was gut / schlecht ist, dekodiert. Die Tutorials, die ich bisher gesehen habe, sagen mir entweder, dass ich den Snapshot-Profiler verwenden soll, oder geben mir ein sehr detailliertes Manifest darüber, wie der gesamte Profiler funktioniert. Ist es möglich, den Profiler einfach als Werkzeug zu benutzen, oder muss ich wirklich verstehen, wie das Ganze konstruiert wurde?

EDIT: Tutorials wie diese:

Gmail-Speicherleckfixierung

Verwenden von DevTools

Sind Vertreter von etwas von dem stärkeren Material da draußen, von dem, was ich gesehen habe. Abgesehen von der Einführung des Konzepts der 3-Snapshot-Technik , finde ich, dass sie sehr wenig praktisches Wissen bieten (für einen Anfänger wie mich). Das 'Using DevTools'-Tutorial funktioniert nicht anhand eines realen Beispiels, daher ist seine vage und allgemeine begriffliche Beschreibung der Dinge nicht allzu hilfreich. Was das "Google Mail" -Beispiel betrifft:

Also hast du ein Leck gefunden. Was jetzt?

  • Untersuchen Sie den Haltepfad von ausgelaufenen Objekten in der unteren Hälfte des Profile-Bedienfelds

  • Wenn die Zuweisungsseite nicht einfach abgeleitet werden kann (z. B. Ereignis-Listener):

  • Instrumentieren Sie den Konstruktor des Halteobjekts über die JS-Konsole, um den Stack-Trace für Zuordnungen zu speichern

  • Verschluss verwenden? Aktivieren Sie das entsprechende vorhandene Flag (z. B. goog.events.Listener.ENABLE_MONITORING), um die creationStack-Eigenschaft während der Konstruktion festzulegen

Ich bin verwirrt, nachdem ich das gelesen habe, nicht weniger. Und wiederum sagt es mir nur, dass ich Dinge tun soll , nicht wie ich sie machen soll. Aus meiner Sicht ist die gesamte Information entweder zu vage oder würde nur für jemanden Sinn machen, der den Prozess bereits verstanden hat.

Einige dieser spezifischeren Probleme wurden in Jonathan Naguins Antwort unten angesprochen .







Sie können auch die Registerkarte Zeitleiste in Entwicklertools anzeigen. Zeichnen Sie die Verwendung Ihrer App auf und überwachen Sie die Anzahl der DOM-Node- und Event-Listener.

Wenn das Speicherdiagramm tatsächlich ein Speicherleck anzeigen würde, können Sie den Profiler verwenden, um herauszufinden, was undicht ist.




Related