6

Ich debugging meine App für Speicherverluste mit den Google Chrome Dev Tools: Heap Snapshots und bemerkte etwas seltsam.jQuery's AJAX Speicherverlust von Antworttext?

Ich habe eine AJAX-Anfrage gemacht, um einen großen Blog von JSON zu holen, und anscheinend bleibt der rohe Response-Text im Speicher stecken, was zu einem Speicherleck in meiner App führt.

Es erschien mir unwahrscheinlich, dass es ein großes Speicherleck in $ .ajax gibt, aber ich hoffte auf eine Erklärung, warum das der Fall ist ... Wenn ich das gleiche Experiment in Vanille JS mache, ist das Leck nicht gezeigt.

1) Reine JavaScript XHR

2) Mit $ .getJSON gezeigt

Screenshot: der gesamte HTTP-Antwort des XHR Anfrage stecken herum Erinnerung. "Snapshot 1" ist vor dem Drücken der Taste. "Snapshot 2" ist danach. Beachten Sie den Screenshot unten und es ist der Vergleich des Vorher/Nachher des Heaps.

Das gleiche Verhalten wurde in der Pure-JS-Version nicht reproduziert.

enter image description here

(Natürlich ist die HTMLDivElement wird noch im Haufen bleiben, da es in dem DOM ist, aber es scheint nicht notwendig, dass das volle JSON-Objekt in dem Heap bleibt)

+0

Konnte mit der Tatsache in Beziehung stehen, dass $ .getJSON ein Versprechen zurückgibt. –

+0

@JulianAubourg gibt es einen Workaround/Weg, um es zu vermeiden? Ist es ein jQuery-Bug oder erwartetes Verhalten? – philfreo

+0

Nun, es ist das erwartete Verhalten, dass alle Ajax-Helfer ein Versprechen abgeben (und somit wird das JSON für die gesamte Lebensdauer des Versprechens im Speicher gehalten). Wir haben sehr sorgfältig darauf geachtet, das XHR-Objekt zu dereferenzieren, um unnötige Speichererhaltung zu vermeiden. Was komisch ist, ist, dass das Versprechen in Ihrem Fall nicht vom Müllsammler zurückgefordert wird. –

Antwort

5

Diese video zeigt, dass tatsächlich dort ist kein Speicherleck. jQuery ruft die neue Version der Zeichenfolge ab und v8 gibt die alte Version frei. Der Grund für dieses Verhalten liegt in der Tatsache, dass die V8-Engine viele verschiedene Tricks zur Optimierung verwendet und eine Referenz auf ein Objekt in seinen internen Strukturen und generierten Code behalten kann.

Die blauen Balken im Video sind die Momente, in denen der Profiler neue Objekte/Strings im V8-Heap gefunden hat. Die Balken werden grau, wenn v8 diese Objekte als Abfall sammelt.

+0

Ihr Video zeigt, dass bei mehreren Ajax-Abrufen nur ein großer blauer Balken übrig bleibt, aber es zeigt nicht, dass es bei der Single/Nearest-Anfrage kein Leck gibt. Also ich verstehe immer noch nicht, warum der Nicht-jQuery-Code nicht das Problem zeigt, aber der jQuery-Code tut ... und wäre nett zu verstehen, eine einfachere Art zu sagen, basierend auf Screenshots wie meins über was wirklich ist ein Leck und was nicht. – philfreo

+4

Aus meiner Sicht, wenn ein neues Objekt erscheint und bleibt nach jeder Iterationen/Aktion in Heap, zum Beispiel wenn ich eine Taste 10 Mal gedrückt und 10 Objekte in Heap, ist es ein Leck. es sollte zumindest eine lineare Abhängigkeit zwischen der Anzahl der Benutzeraktionen und der Menge des verwendeten Speichers bestehen. In Ihrem Fall speichert die Javascript Engine das Ergebnis aus irgendeinem Grund und gibt es beim nächsten Drücken der Taste wieder frei. – loislo

+0

Ich kaufe das, aber es scheint falsch/verwirrend zu sein, dass Chrome Zeug im Heap-Snapshot speichert, auch wenn es keine externe Referenz darauf gibt - nachdem eine Garbage Collection ausgeführt wurde (was passieren sollte, bevor der Snapshot erstellt wird) . Es macht es schwierig, Speicherlecks zu debuggen, es sei denn, es handelt sich um eine Aktion, die immer wieder wiederholt werden kann. – philfreo

0

Vielleicht etwas fehlt, aber jsfiddles am ursprünglichen Beitrag erscheinen die gleichen Ergebnisse zurück? Auch

würde

$.ajaxSetup({cache : false})

Ergebnisse beeinflussen?

Um den Browser-Cache in Chrom/Chrom-Browser, bei Terminal (* nichts) versuchen

find ~/.cache/chromium/Default/Cache -type f -exec rm -f {} \;

find ~/.cache/chromium/Default/Media\ Cache -type f -exec rm -f {} \;

ersetzt chromium mit chrome zu löschen, wenn nötig. Alternativ navigieren Sie zu dem

chromium oder chrome Ordner im Gerät, navigieren Sie zu jeder Default und Media Cache Ordner innerhalb und Inhalte löschen.

+0

Soweit ich sagen kann, bezieht sich "Cache" hier auf den Browser Zwischenspeicherung der HTTP-Antwort auf der Festplatte auf der Grundlage der Caching-Header der HTTP-Antwort ... nicht ob seine zwischengespeicherten im Speicher. – philfreo

+0

Wie oben erwähnt, schien, die gleiche Antwort zu erhalten, das ist "X" 's Füllung Bildschirm bei beiden jsfiddles jsfiddle.net/HZmT5/2 jsfiddle.net/JmA8v/1? Chrom/Chrom-Devtools können mehrere "Schichten" von "Speicher" bereitstellen, abhängig von der verwendeten Devtool-Registerkarte. Wie oben ausgeführt _ "Der Grund für dieses Verhalten ist die Tatsache, dass V8-Engine viele verschiedene Tricks zur Optimierung verwendet und einen Verweis auf ein Objekt in seinen internen Strukturen und generierten Code behalten kann." - loislo_. Was ist die Anforderung? Bitte klären Sie. Vielen Dank – guest271314

Verwandte Themen