2014-05-09 10 views
6

Stavo eseguendo il debug della mia app per perdite di memoria con Google Chrome Dev Tools: Heap Snapshots e ho notato qualcosa di strano.jQuery's AJAX perdita di memoria del testo di risposta?

Ho fatto una richiesta AJAX per recuperare un grande blog di JSON e apparentemente il testo di risposta non elaborato è rimasto in memoria, causando una perdita di memoria nella mia app.

Mi sembra improbabile che ci sia un'enorme perdita di memoria in $ .ajax, ma speravo in una spiegazione del perché questo è il caso ... se faccio lo stesso esperimento in Vanilla JS la perdita non è mostrato.

1) Pure XHR JavaScript

2) Uso di $ GetJSON

Screenshot: l'intera risposta HTTP della richiesta XHR bloccato intorno a memoria. "Istantanea 1" è prima che il pulsante venga premuto. "Snapshot 2" è dopo. Si noti lo screenshot qui sotto ed è il confronto del prima/dopo dell'heap.

Lo stesso comportamento non è stato riprodotto nella versione JS pura.

enter image description here

(Naturalmente il HTMLDivElement rimarrà nel mucchio dal momento che è nel DOM, ma sembra inutile che l'oggetto completo JSON rimane nel mucchio)

+0

Potrebbe essere correlato al fatto che '$ .getJSON' restituisce una promessa. –

+0

@JulianAubourg c'è una soluzione/modo per evitarlo? È un bug jQuery o un comportamento previsto? – philfreo

+0

Bene, il comportamento previsto è che tutti gli helper di ajax restituiscano una promessa (e quindi il JSON viene tenuto in memoria per tutta la durata della promessa). Ci siamo presi molta cura del dereferenziamento dell'oggetto XHR per evitare inutili ritenzione di memoria. La cosa strana è che la promessa non è reclamata dal garbage collector nel tuo caso. –

risposta

5

Questo video dimostra che in realtà non vi non c'è perdita di memoria. jQuery recupera la nuova versione della stringa e v8 rilascia quella precedente. La ragione di questo comportamento è il fatto che il motore V8 utilizza molti trucchi diversi per l'ottimizzazione e può mantenere un riferimento a un oggetto all'interno delle sue strutture interne e del codice generato.

Le barre blu nel video sono i momenti nel tempo in cui profiler ha trovato nuovi oggetti/stringhe nell'heap v8. Le barre diventano grigie quando v8 raccoglie questi oggetti come rifiuti.

+0

Il tuo video mostra che su più ajax recupera solo una barra blu alta rimane, ma non sta mostrando che non c'è una perdita con la richiesta singola/ultima. Quindi ancora non capisco perché il codice non-jQuery non mostri il problema, ma il codice jQuery ... e sarebbe bello capire un modo più semplice per distinguerlo basato su screenshot come il mio sopra ciò che è veramente una perdita e cosa non lo è. – philfreo

+4

Dal mio punto di vista se un nuovo oggetto appare e rimane nell'heap dopo ogni iterazione/azione, per esempio se ho premuto un pulsante 10 volte e ottenuto 10 oggetti in heap, è una perdita. cioè dovrebbe esserci almeno una dipendenza lineare tra il numero di azioni dell'utente e la quantità di memoria utilizzata. Nel tuo caso il motore javascript memorizza semplicemente il risultato nella cache per qualche motivo e lo rilascia la prossima volta che premi il pulsante. – loislo

+0

Comprerò questo, ma mi sembra sbagliato/confuso che Chrome stia segnalando elementi archiviati in memoria nell'Heap Snapshot anche dove non ci sono riferimenti esterni ad esso - dopo che viene eseguita una raccolta di dati inutili (che dovrebbe accadere prima che prenda l'istantanea) . Rende difficile il debug delle perdite di memoria a meno che non sia un'azione che può essere ripetuta più e più volte. – philfreo

0

Forse manca qualcosa, ma i jsfiddles al post originale sembrano restituire gli stessi risultati?

Inoltre, sarebbe

$.ajaxSetup({cache : false})

influenzare i risultati?

Per cancellare la cache del browser al cromo del browser/cromo, a Terminal (* nix) cercano

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

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

sostituzione chromium con chrome, se necessario. In alternativa, accedere alla cartella

chromium o chrome al dispositivo, passare a ogni Default e Media Cache cartelle all'interno, e cancellare il contenuto.

+0

Per quanto ne so, 'cache' qui si riferisce al browser che memorizza nella cache la risposta http su disco in base alle intestazioni di cache della risposta http ... non se la cache è in memoria. – philfreo

+0

Come accennato a post, sopra, è sembrato derivare la stessa risposta, cioè lo schermo di riempimento di "X", in entrambi i jsfiddles jsfiddle.net/HZmT5/2 jsfiddle.net/JmA8v/1? Chrome/deviools di cromo può fornire diversi "livelli" di "memoria", a seconda della scheda devtools utilizzata. Come sottolineato in precedenza _ "La ragione di questo comportamento è il fatto che il motore V8 utilizza molti trucchi diversi per l'ottimizzazione e può mantenere un riferimento a un oggetto all'interno delle sue strutture interne e del codice generato." - loislo_. Qual è il requisito? Si prega di precisare. Grazie – guest271314