A Firefox és a Gecko nagy memóriahasználatának elemzése, oka, lehetséges javítása

Címkék

A Red Hat-os Christopher Blizzard - aki egyébkét helyet foglal a Mozilla Corp. igazgatótanácsában is - blogjában előveszi a már sokak által megénekelt Firefox/Gecko engine memóriafoglalási és kezelési problémakört. Mint írja, a számokat nézve a panasz jogos lehet, de ez csak az érem egyik oldala. Tudja, hogy a Mozilla fejlesztők komolyan veszik a memóriaszivárgási problémákat és amint rábukkannak egy ilyen bugra, javítják a hibát. De akkor mi lehet az, amit a felhasználók érzékelnek és mi az, amit a fejlesztők látnak?

Ahogy a Mozilla fejlesztők egyre jobban ráfekszenek a mobil eszközökre való fejlesztésre, úgy kap egyre nagyobb hangsúlyt a memóriakérdés és a gazdaságos memóriafelhasználás. Blizzard szerint Vladimir Vukićević (vlad) és Stuart Parmenter (a RAMBack add-on szerzője) nekiálltak kivizsgálni az (memória)allocator viselkedését néhány egyszerű teszt alatt.
Az első teszteredmények azt mutatták, hogy a Mozilla önmagában nem szivárogtat el olyan sok memóriát mint amit neki tulajdonítanak, sokkal inkább keményen gyötri az allocator-t, memóriatöredezettség lép fel és ez az, ami a memóriaszivárgási érzetet kelt. A fejlesztők úgy tűnik, hogy rászívódtak a problémára. DTrace-szel és elszántsággal felfegyverkezve próbálják kiküszöbölni a káros memóriafragmentációt.

A Stuart Parmenter további infókat ígér hamarosan.

A dologról részletesen, pontosan, képekkel illusztrálva itt lehet olvasni.

Hozzászólások

Én is örülök. :)

Egyébként bocs a láma kérdésért, lehet, hogy csak vaksi vagyok, de múltkor egy órát keresgéltem hiába... szal nem tudja valaki, hogy hol lehet belenézni a Firefox fejlesztői doksijaiba vagy forrásába? Kerestem volna valamit... Kösz.

nekem a fő bajom a firefox-szal hogy baromi lassú :(
bár mintha otthon (Slackware 12) egész gyors lenne, de a notin (Ubuntu Gutsy) iszonyatosan tekeri a procit már egy-két prohardver oldallal is, az opera 20-30 füllel is sokkal gyorsabb

Szerintem nem olyan sok az a memória. Most nézem:

firefox 29.7MB
nautilus 14.4MB
gnome-panel 8.1MB
mixer-applet 4.4MB!

Amúgy én nem DTrace-szel meg elszántsággal fegyverkeznék föl, hanem libgc-vel.

--
CCC3

Klasszikus malloc szar, nem gc kell helyette hanem normali malloc.

Valoszinuleg nem felszabaditatlan blokkrol lehet szo azt egy kurva valgrind is megtalalja.
Valami amire meg van "referencia" de nem hasznaljak.


#include <malloc.h>
int main()
{
int a;
void *p[65536];
p[0]=malloc(4096);
getchar();
for (a=1;a<65536;a++)
{
	p[a]=malloc(4096);
	p[a-1]=realloc(p[a-1],1);
}// 4096+a   a lefoglalt memoria, topot sasolni, a*4096 megy el valójában.
getchar();
for (a=0;a<65536;a++)
{
 free(p[a]);
}
getchar();
return 0;
}

Igy kell fregmentalni. (0.1% alatt van a hasznos memoria)

Elsore jo taktikanak tunhet amit reallocal művel az ember, tul foglalja memet aztan szugsegesre kicsinyiti ,valojaban nem mindig olyan jo dolog az.

Az is jó ötletnek tűnik, hogy a realloc ne mozgasa át a memoriat (copy megsporolása), ha nem szükséges (kisebb területre váltáskor nem teszi).

Aki ezeket nem tudja..
szerk:
az biztos c++-ban máskép kodól, mint c -ben :)

Igen, ugye Javaban ezt ugy csinaljak, hogy a nyelv tipus konstrukcioi lehetoseget biztositanak arra, hogy a komplett memoriat az applikacio alatt defragmentald, igy ott ez a problema nem jon elo... C++-ban ezt nem tudod megcsinalni a direkt pointerek miatt, igy en a legjobb megoldasnak valamifele hierarchikus memoria managert tudnek elkepzelni, pl hogy van egy globalis manager, ami mondjuk fel megakat osztogat, van ezek alatt mondjuk egy tabpage-hez tartozo memoria manager (tabpagenekent), ami a globalistol ker, es a sajat elemeinek osztogat sokkal kisebb felbontasban, es igy tovabb, igeny szerint. Az se art, ha egy lokalis manager inkrementalisan adja ki a foglalasokat, igy lesznek olyan pontok, ahol egyszerre sok memoriat lehet visszaadni.

Linux kernelben egesz jo strategiak vannak.

Leginkabb lassu, az a baj mallocal.

Egy kurva egyszeru strategia free lapok log_2(size) szerint listazva (64 lista) mar oriasit dobhat a sebessegen, es nem a nagy szabad blokkokbol csinal kicsit, ha ep olyan sorendbe van. (nem ez legjobb, de legkevesebb vizet zavar)

Nem ártana még, hogy valahogy freenél megnézze nem e szomszédos egy mások szabad blokkal és akkor egyesülne. Gyakori, hogy az egymás után allokált dolkokat egymás után free-zik tehát legutóbbi három felszabaditást megnézve, is jó eséllyel lesz illeszkedés.

ps:
glibc -ben pöttyet értelmesebb malloc, van mint rémlett, már vagy 2.3 óta :)

A kernelnek meg van az az elonye, hogy komplett lapokat kell osztogatnia, amelyek a processzor memoria virtualizacios kepessegei miatt szinte fuggetlen sorrendben lehetnek. Ha jol emlekszem egy komplett processz virtual address space szinte barmilyen fizikai sorrendu lapokat tartalmazhat, es altalaban tartalmaz is. (Ha nem mondok igazat javitsatok ki.) A process linaris adsress spacet kezelni mer kemenyebb dio.

Szerintem itt nem a sebesseg a problema, hanem a fragmentacio. Azt pedig a memoria manager logikai strukturalasaval, illetve a memoria foglalasok idobeli figyelembevetelel (inkrementalis foglalas) lehetne a legjobban kezelni.

A te algoritmusod mi csinal abban az esetben, ha mondjuk egyenletes elszlasu meretu memoria teruleteket kernek tole 16byte-tol 2048 byteig, es egyenletes elszolassal szabaditjak fel?

Flame on

Nem ide tartozik, de a Vissza gombbal visszajutok oda ahol voltam, pl.: az oldal közepére, vagy még mindig az oldal elejére dob. Kurva idegesítő állandóan visszagörgetni oda, ahol voltam. Ezért nem használom, meg a memóriaszarságai miatt, és tetű lassú is.

Opera fényévekkel jobb.

Flame off

Nemtom hogy a memoriahasznalattol-e, de inkabb nem, de idonkent a FF rohadtul be tud lassulni a nagyobb oldalaktol.

Egyszeruen reprodukalhato, tesztelheto itt:
http://hup.hu/node/46959

A lap aljan (de fent is) rohadt lassu a scrollozas (mind1 hogy egergombbal vagy billentyuzettel). Btw, most nezem, hogy az oldalso gorgetosavval viszont egesz gyors. Hmm.

Ja meg Safari-val ugyanez az oldal tok gyors mindegy mivel gorgetem.

OSX 10.5 amugy. (btw FF meg lassabbnak tunik meg 10.4-en volt)

A'rpi

Basszuskulcs.
malloc() mmap()/munmap() al jatsza memoria foglalast.
g++ (vector::)new() meg brk()?

Nem lehetseges, hogy ebbol kifolyolag memoria tunik el ? unmappolt lap -t egy brk() ujra berant ahol azt hiszi, hogy data resz vegere foglalt csak?

szerk:
Nem mindig brk()-t hasznal, majd megnezem mikor, de nekem ez vesszelyes uzemnek tunik.