Boehm féle szemétgyűjtés

Fórumok

Korábban is tudtam, hogy a GNU Jáva és a Mono Boehm-féle konzervatív szemétgyűjtéssel működik. Csak nem jól értettem, miről van szó. Azt ui. fel sem tételeztem, hogy a Jáva és a Mono ne rendelkezne saját szemétgyűjtéssel. Ezért azt hittem, hogy a "Boehm-féle konzervatív" egy algoritmust jelent, amit implementáltak a Monoban.

Hát nem így van. A Boehm szemétgyűjtés egy kész implementáció, könyvtár (libgc), ami eleve installálva van az Ubuntun. Ezt a könyvtárat _tetszőleges_ C program belinkelheti. A "konzervatív" jelzőn azt értik, hogy a szemétgyűjtés nem igényel semmiféle compiler támogatást.

Miután megértettem, hogy erről van szó, (próbaképpen) kicseréltem a variable.cpp-t egy olyan példányra, amiben a globális függvényeknek dummy (üres) implementációja van. Az egészet lefordítottam egyszálúra (eddig 20 perc munka) és most futnak a CCC programok Boehm szemétgyűjtéssel.

Most ezt nézegetem. Egyelőre csak egyszálú programokon, de elvileg mennie kell többszálon is.

Hozzászólások

A szomszéd kertjében mindig jobb a szemétgyűjtés? :D

w

sed 's/szemétgyűjtés/garbage collector/g'

Dw.

"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."

Még plusz 10 sor (mondjuk ez már fél nap volt), és megy a többszálú CCC Boehm szemétgyűjtéssel.

--
CCC3

Még nem raktam fel a Boehmöset. Majd szólok.

A Boehmös program másfélszer nagyobb helyet foglal a memóriában, viszont kétszer gyorsabban fut. Gondolom, ez amiatt van, hogy nagyobb adag memóriát elkér az OS-től, és abban saját maga gazdálkodik (hatékonyan). A Boehm nélküli program viszont minden memóriát nyersen és primitíven malloc-kal (Windowson GlobalAlloc-kal) foglal le, az OS pedig bajlódik a fragmentált memóriával.

A natív szemétgyűjtés a maga primitívségében abszolút hordozható, és a jég hátán is meg lehet élni vele. A Boehmös (egyelőre) rosszul működik Solarison, nem próbáltam még FreeBSD-n, egy napomba került, amíg felélesztettem Windowson (MinGW-vel).

Azért az érdekes lesz, ha a CCC ugyanazzal a szemétgyűjtéssel működik, mint a Mono.

--
CCC3

Hát, én becsülettel nekifutottam Windowson, de visszapattantam. GC_CreateThread-et hiányolt, meg aztán már __errno-t is, meg mindenféle sig... függvényeket. Úgy tűnik, megfeküdte a MinGW gyomrát a sok Cygwin-es könyvtár. De őszintén szólva a gondolat, hogy pusztán egy Z lefordításához olyan külső függőség legyen, amihez már nem elég a MinGW, nem szimpatikus.

w

Nyilván nem jól csinálod. Cygwin nem kell. A libgc MSYS környezetben, default opciókkal, MinGW-vel símán lefordul. Hogy ezzel ne kelljen bajlódni, felraktam az eredményt a comfirm.hu-ra.

A compile.opt-ba beírod: -DGC_BOEHM.
Ugyanonnan kiveszed: -DGC_NATIVE
A link.opt-ba beírod: -lgc
Mindent újrafordítasz: clean-all.b, i.b

--
CCC3

Tényleg nem jól csináltam valamit. Valószínűleg leginkább azt, hogy a Cygwin-es csomagnak nem sok köze van a MinGW-hez. Ezzel a csomaggal, amit feltettél, nagyon szépen muzsikál minden.
Lenne-e szerinted értelme beletenni az SVN-be ezt a libgc-t forrással, mindennel? Csak hogy ne törjön meg az a szép hagyomány, hogy egy svn co és egy install parancs mindent megold :)

w

Hát szerintem nem. A libgc nem része a CCC-nek, mások fejlesztik, más licensze van. Linuxon van belőle kész csomag, csak installálni kell. Ezért úgy gondoltam, hogy egyelőre a natív szemétgyűjtés marad a default, ilyen beállítások töltődnek le (hogy ne törjön meg a szép hagyomány). Aki kisérletezni akar a Boehm szemétgyűjtéssel, az csinál magának libgc-t. Egyébként ezen még ráérünk gondolkodni.

--
CCC3

Nem volna-e jobb a GTK-ban, C-Pythonban a libgc-re alapozott szemétgyűjtést használni az elavult és nehézkes referenciaszámlálás helyett?

Szerk:

Itt a válasz: http://arctrix.com/nas/python/gc/
Van Boehm szemétgyűjtéssel patchelt Python, de az csak kiegészítése a referenciaszámlálásnak (szvsz úgy nem sokat ér).

--
CCC3

Felraktam ide egy kis pamfletet, amiben összehasonlítom a Boehm-ös szemétgyűjtést az eredetivel.

--
CCC3

Nos, jelentem, több, mint egy hete nyúzom Linuxon és Windowson egyaránt a Boehm-féle GC-t, és eddig nem találtam semmi olyan problémát, ami összefüggött volna vele. Sőt, talán még mintha egy hangyabokányit stabilabb is lenne. A Z editor megcsinálta velem már egyszer-kétszer azt, hogy szó nélkül becsukódott, ismeretlen okból, ezt nem tapasztalom Boehm-mel, de nem is megy még elég ideje a Boehm ahhoz, hogy ezt statisztikai mintának lehessen tekinteni :)

w

Sőt, talán még mintha egy hangyabokányit stabilabb is lenne.

Borzalmas, amit írsz, ui. ez azt jelenti, hogy a másik kevésbé stabil, holott egyedül csak az elfogadható, ha mindkét verzió teljesen stabil.

A z editor leggyakrabban úgy szokott elszállni, hogy becsukják azt az xterm ablakot, amiből indították. Ilyenkor a program HUP signált kap, amire kilép.

A CCC programok úgy is el szoktak szállni, hogy fejlesztgetés közben felülíródik egyik vagy másik shared lib, amit a futó program használ. Ilyenkor a program gyakran "elszabadul", felemészt minden CPU-t, néha még kílőni is nehéz. Ez a z-t nem érinti, mert azt éppen emiatt statikusra szoktam linkelni.

--
CCC3

Hát, a helyes állítás az alábbiképpen hangzik:
A sok gépem közül az egyiken előfordult mondjuk háromszor az, hogy egy Z editor ablak hirtelen eltűnt, anélkül, hogy lementette volna az editálásaimat, tehát nem F10-et nyomtam véletlenül.
Ez valószínűleg összefügghet egyébként a hálózattal valahogy, mert ugyanez a gép néha eldobja a hálózatot egy pillanatra, és aztán újra magára talál, kvázi 'laggol' egyet. Az Általad említett dolgokat nem tapasztaltam, igaz, nem xterm-et használok, hanem Konsole-t, és nálam is statikusra van linkelve a Z.
A 'hangyabokányit' arra vonatkozott, hogy ha mondjuk naponta átlagosan ötszázszor indítok el Z-t, ami kb. reális, és Z-t használok kb. fél éve, és ebből volt 3 lefagyás, akkor ez eleve egy 'hangyabokányi' statisztikai adat, tehát nem is bír sokkal javulni, csak ennyivel :D
Egyébként elenyészően ritka az, hogy egy program SIGSEGV-zzen, és eddig minden esetben kiderült, hogy hibás .so-k felrántása okozta a gondot. Az "elszabadulós" esetet még nem láttam sose.

w

Igen, de ezek a dolgok remélhetőleg nem függnek a szemétgyűjtéstől.

Mielőtt a z hiba miatt kilép, még megpróbálja lementeni az editált fájlt ~/.z-ben. Ahogy most megnéztem, ez sajnos nem működik, ha a z amiatt lép ki, mert megszakadt a kapcsolat a terminal.exe-vel, pl. becsukják a terminal.exe ablakát. Ezt majd egyszer kijavítom.

Közönséges programhiba, vagy SIGSEGV nem gyakori, csak akkor lehet, ha valamit elszúrok. Ami gyakori: SIGTERM, pl. ha CTRL-C-t nyomnak a z-nek. SIGHUP, ha kilép a z parentje, pl. ha az z-t xterm-ből, vagy konsole-ból indítják, aztán kilépnek belőle. Ezekben az esetekben működik a mentés.

--
CCC3

A websrv egy kicsi (kevesebb mint ezer sor) többszálú demó HTTP szerver. Minden új klienst új szál szolgál ki. Egy szál mindaddig fut, míg a kliens tartja a TCP kapcsolatot és 10 másodpercen belül újra kérdez.

A websrv nagyon alkalmas a többszálú futtatókörnyezet stabilitásának tesztelésére. Egy tesztprogrammal folyamatosan wget klienseket indítok, egyszerre 8-10-et tartok életben, mindegyik tükröz egy websiteot, amiben PHP és CGI oldalak is vannak. A websrv így órákon keresztül folyamatosan ~6 szálon dolgozik, miközben többmillió requestet szolgál ki.

A natív szemétgyűjtéssel már évek óta nem adódik hiba. Baj van viszont az (alternatív) Boehm-féle szemétgyűjtéssel.

A boehmös websrv hibázik a CCC könyvtári asort függvényben. A CCC asort a C könyvtári qsort-on alapszik. A qsort-nak az a baja, hogy a rendezendő tömb elemeit _byteonként_ cseréli fel. Namost, ha a tömb pointereket tartalmaz, és a gc olyan pillanatban néz egy ilyen pointert, amikor az éppen el van felezve, akkor a mark&sweep algoritmus mark része nem tud jól lefutni.

Ha a qsortot saját implementációval helyettesítem, ami CCC valuekat nem pedig byteokat cserélget, akkor a hiba megszűnik. Részletesebben: Linuxon és FreeBSD 7.1-en Boehm-gc-vel, C könyvtári qsorttal hamar kijön a hiba. Saját qsorttal akármilyen hosszú teszteléssel sem jött ki hiba (eddig). Windowson a helyzet rosszabb, a többszálú Boehm gc sehogy sem stabil.

A qsort hibáját könnyen ki lehet kerülni, de feltehető, hogy a mostani irdatlan nagy könyvtárakban máshol is vannak ilyen lyukak. A végeredmény tehát, hogy a Boehm-gc nem alkalmazható többszálú programokban. Kár érte. Talán úgy lehetne javítani a helyzeten, ha a libgc jobban integrálódna a compilerrel.

A CCC-ben alkalmazott Boehm gc csak egy kísérlet. Mondhatnám, hogy érdektelen, mert az éles alkalmazásokban úgyis a natív gc fut. Vannak viszont olyan projektek, amik a Boehm gc-re (libgc) alapoznak, mint a Mono és GCJ. Ezeknek saját szemétgyűjtésre kell áttérniük.

--
CCC3

Mivel jobb egy saját GC, ha a probléma oka az, hogy a pontereket nem atomi módon mozgatjuk, így időnként feldarabolva lapulnak a memóriában? Ill. ez miért csak a Boehm-gc-nél probléma? Mi van, ha éppen földarabolt állapotban van egy pointer és bevág egy másik szál, amelyik hivatkozik rá?
(Vagy félreértem a folyamatot?)

KisKresz

Boehm-féle konzervatív szemétgyűjtés.

Boehm a krapek, aki kitalálta. A "konzervatív" azt jelenti, hogy semmit nem tételez fel a fordítóról, programról, hanem lényegében egy tetszőleges programban le tudja takarítani a nem hivatkozott memória-objektumokat.

Mark & sweep algoritmussal működik. Mark=bejelöl, sweep=takarít. A stackről kiindulva a program _minden_ pointernek kinéző adatát pointernek tételezi fel, ami egy memóriablockra mutat, abban szintén minden adatot pointernek feltételez, stb. (gráfbejárás). Bejelöli azokat a memóriablokkokat, amiket így elér (mark). Az összes többi memóriablokkot (tehát, amiket nem ért el) kitakarítja (sweep).

Az itt a baj, hogy a Boehm-gc semmilyen segítséget nem kap a programtól. Pl. az is csak egy feltételezés, hogy mik a pointerek. Egy natív szemétgyűjtés viszont együttműködik a futtatórendszerrel. Ismert, hogy hol vannak pointerek. A pointerek mozgatása lockolja a gc-t.
--
CCC3

Igaz. Csak hát honnan lehet tudni, hogy mit kell szinkronizálni és mit nem. A qsort véletlenül kibukott, de vannak irdatlan méretű könyvtárak, mondjuk ssl, gtk... és azokban a qsorthoz hasonló lyukak.

Egy szemétgyűjtésre eleve felkészített program természetesen mutexekkel szinkronizálja a szemétgyűjtést a többi szállal. A libgc viszont szignálokkal állítja le a többi szálat a szemétgyűjtés idejére. Ez mutatja a nehézségeket, ami kifejezetten amiatt van, hogy a libgc a befogadó programtól "függetlenül" dolgozik.

A "függetlenül" azt jelenti, hogy egy lényegében tetszőleges C programban csak a malloc-ok és a thread kreálás van lecserélve. A qsortról nincs szó. Nincs is API a szinkronizálásra. Talán a szignálok maszkolását lehetne használni. De hát akkor elvész a transzparencia, ami az egész legfőbb értéke volna.
--
CCC3

mono miert nem hosszu o, ha a java ekezetes?! ;)
___
info