← bitàcola

El que el navegador es guarda

La memòria és una funcionalitat, i oblidar també

Quatre dels canvis d'aquest lot van de què reté el motor: una memòria cau que ho guardava tot i ho perdia tot en sortir, galetes que existien només si tancaves amb educació, un servidor de devtools gravant una sessió que ningú no mirava, i una pàgina que explica per a què és la seva memòria. I un és el problema contrari — alguna cosa retinguda exactament un frame de més.

La memòria cau tenia un tier i el límit equivocat

La memòria cau HTTP guardava totes les respostes a la memòria, comptades per entrades i no per mida, i ho perdia tot en sortir. Comptar entrades vol dir que mil favicons i mil segments de vídeo costen el mateix, que és justament el que un límit per mida hauria d'impedir.

Ara té dos tiers. El tier de memòria està acotat pels bytes dels cossos que guarda, configurat amb network_http_cache_memory_size. El tier de disc conserva respostes completes entre reinicis sota Opts::cache_dir, fins a network_http_cache_disk_size, i només el té la sessió pública — una sessió temporal amb memòria cau a disc no seria temporal.

Cada fitxer s'escriu amb un nom temporal i es reanomena al seu lloc. Un crash a mitja escriptura deixa per tant el fitxer anterior intacte en lloc d'un de truncat, cosa que importa més del que sembla per a una memòria cau: una entrada mig escrita no és una resposta que falta, és una resposta equivocada.

Galetes, escrites en marxa

El pot de galetes públic, la llista HSTS i la memòria cau d'autenticació s'escrivien a config_dir només quan el resource thread rebia Exit. Un embedder que petava, o que mataven, perdia totes les galetes de la sessió — i un embedder en desenvolupament el mates constantment.

Un fil de fons les escriu ara cada 30 segons quan han canviat, per la mateixa ruta de fitxer temporal i rename. Com que el fitxer a disc pot contenir ara galetes de sessió, el que s'escriu s'ha hagut de decidir en lloc de donar-se per fet.

Un servidor de devtools sense públic

El servidor de devtools guardava tots els esdeveniments de xarxa, inclòs el cos de cada resposta, i una còpia del text de cada font que veia, scripts en línia inclosos, mentre estigués corrent. Sense cap client connectat a qui mostrar-los, allò eren totes les pàgines carregades, a la memòria, durant la vida del procés.

Sense client, els esdeveniments de xarxa es descarten ara. Els actors de fonts es continuen creant, així que una font apareix llistada en el moment en què un client es connecta, però no guarden text fins que hi ha algú a qui enviar-l'hi.

about:memory, en paraules

La pàgina llistava les rutes crues dels informes de memòria, que són les dades correctes i la presentació equivocada: js-main-runtime/compartments/system et diu d'on surt un número, no si és un problema.

Ara anomena cada part en paraules planes, diu si aquella memòria se'n va i quan, i agrupa els informes per pàgina. També pot tornar a mesurar, demanar a totes les pàgines que recullin escombraries, i obrir un conjunt de llocs pesants per carregar el navegador — les tres coses que fas de debò quan persegueixes una fuita, en lloc de llegir un número un cop.

Una nota de build que és fàcil passar per alt: jemalloc ha d'estar construït amb les seves estadístiques, o stats.allocated i la resta no existeixen i l'informe no té cap xifra del heap. El text de la pàgina és en castellà, com la resta de la interfície.

SAME BUFFER ID, THREE FRAMES fence import no fence reuse the import fence import again the producer hands out a fence once per write, which is the only signal that the contents moved the old rule: keep the import while the buffer id is unchanged a write under a kept import shows the previous contents — a black page after a resize on NVIDIA The buffer id says which buffer it is. It never said whether anything was written to it.

L'import que va sobreviure a una escriptura

L'altra direcció del mateix error. GPUI mantenia el seu import d'un dmabuf mentre l'id del buffer no canviés, cosa que sona bé: l'id diu quin buffer és, i el buffer no s'ha canviat.

L'id diu quin buffer és. No va dir mai si s'hi havia escrit res. Un import mantingut a través d'una escriptura del productor continua presentant el que el buffer tenia abans — cosa que a NVIDIA apareixia com una pàgina en negre després d'un redimensionat, el símptoma més confús possible per a un bug de memòria cau, perquè res que hi hagi no apunta a una memòria cau.

El productor entrega una fence un cop per escriptura, i aquesta és l'única senyal que el contingut s'ha mogut. Un frame que rep una fence torna a importar el buffer; els frames que no porten res de nou reutilitzen l'import.

Dos més, mentre comptem coses mal retingudes

document.visibilityState era hidden per a tots els documents fins que es reactivaven des de l'historial de sessió, i després no canviava mai. Una pàgina que espera a ser visible abans de carregar o reproduir alguna cosa no ho feia per tant mai. Un document que carrega en un webview que no està throttled comença ara visible; fer throttle a un webview, que és com diu un embedder que ha deixat de mostrar-lo, oculta el document i dispara visibilitychange, i treure'l ho reverteix.

I un receiver de crossbeam tancat està sempre llest, així que tan bon punt desapareixia un sender d'un conjunt de receivers, cada select posterior tornava immediatament amb el mateix ChannelClosed i els receivers que continuaven oberts no es llegien més. El receiver tancat es reemplaça per un que no està llest mai, cosa que manté els ids dels altres sense canviar — el detall que fa que l'arranjament sigui un arranjament i no una renumeració.

El que continua sense acotar

La memòria cau de disc té un límit de mida i cap política de desallotjament que mereixi el nom més enllà d'ell. about:memory informa del heap només quan jemalloc es va construir per explicar-ho, cosa que vol dir que les xifres falten justament en els builds que faria servir algú.

I la contenció del servidor de devtools depèn que no hi hagi cap client connectat. Enganxa-li un a una sessió llarga i l'acumulació torna, perquè les dades que un client podria demanar continuen sent tot el que ha vist.

BEFORE: EVERY RESPONSE IN MEMORY, COUNTED BY ENTRIES, LOST AT EXIT memory tier bounded by the bytes of its bodies network_http_cache_memory_size disk tier complete responses under cache_dir network_http_cache_disk_size survives a restart · public session only temporary name, then rename a crash mid-write keeps the previous file The cookie jar, the HSTS list and the auth cache take the same route, written every 30 seconds when changed, not only at exit.
Acotada per bytes i no per un recompte d'entrades, i escrita amb un rename perquè un crash a mitja escriptura conservi el fitxer anterior.