saxus (statz) | #9, Agyfasz (419) |
3111 | #1c30 | ^ | Idézet | Sat, 28 Apr 2012 03:09:14 +02 |
84.3.*.* | *.catv.pool.telekom.hu |
Na a kedvedért készítettem egy kis PoC példát. Illetve többet is: http://shared.muportal.hu/kepek/gc/gc.png Első példa: Szimplán nyitunk egy háttérszálat, kicsit matekolunk 4 megányi inten, majd billentyű lenyomásra kilépünk. GC-t én hívom meg kézzel. Meg is várhatnám, hogy valamilyen eseményre lefusson (pl. ami lehet másik thread memóriaigényétől kezdve akár az is, hogy a a Windows szól a .NET-nek, hogy figyumá, nincs-e fölös ramod, mert esetleg tudnék kezdeni valamit), de nem volt kedvem ennyit várni, így inkább meghívtam én a GC-t. Egyből vissza is esik 40 megára. (Hogy miért nem az induláskori 20-ra, arról majd később.) http://shared.muportal.hu/kepek/gc/gc2.png Következő példa már picit rázósabb, enyhén forkbomb kezdetű: háttérthreadból nyitok további threadeket, igaz azokat be is fejeztetem. Jól látszik, hogy itt azért már jobban ingadozik a memóriahasználat attól függően, hogy mennyi thread kap CPU időt a többi processtől. Befejezéskor nem változik semmi. http://shared.muportal.hu/kepek/gc/gc3.png Gondoltam nézzük meg, hogy mi a helyzet, hogyha a Visual Studio nem birizgálja a processt a háttérből. (Ha megnézed a process tree-t a process explorerben, akkor láthatod, hogy nem a VS host processe, hanem a cmd a parent process) Egyrészt ami egyből szembetűnő, hogy az induláskori memóriahasználat 7,6-ra esett le a kezdeti 20,6-ról és a végállapot 40 mega helyett 10,7 lett, valamint konstans 20,1 mega volt üzem közben mindenféle ingadozás nélkül. Kódon annyit változtattam, hogy ne legyen olyan forkbomb jellegű és várja meg a háttérthread a matekoló thread végét. Próbáltam release és debug módot is, nincs igazán sok különbség. A memóriahasználat különbsége szerintem két dolog számára írható: debugger/intellitrace valamint a HostProcess-nek, ami segít a VS-nek a debuggolásban. Na de ugye még így is megugrik a memóriahasználata a cuccnak. Mondhatnád, hogy leakel, de nem, az igazság ennél prózaibb. :) Ha megnézed a process IO-t, láthatsz egy kis tüskét pont akkor, amikor elindul a háttérthread. Ez akkor hajtódik végre egyszer, amikor a Thread elindul. Gyanítom, ilyeknor tölt be egy rakás Win32 kódot a .NET FW a háttérben és/vagy további szükséges assemblyket és a hozzá tartozó kódokat, amelyek - breaking news - ismét memóriát igényelnek. Ezért készítettem egy olyat, amely matekol 10 másodpercet, vár 10-et, majd újra futtatja. Az eredmény ugyanaz: a GC meghívásakor letakarít midnen letakaríthatót, amit az én kódom hozott létre. http://shared.muportal.hu/kepek/gc/gc4.png Egyébként kísérleteztem még pár dologgal. Pl. próbáltam olyat, hogy a Thread.Start() után még 10 mp-t várni. Olyankor 10-ről. 12,6-ra ugrott fel, amely valószínűleg a két thread stackjának lefoglalt terület meg még egy minimális, amit a .NET a thread kezeléséhez rendelt (pl. managed threadid, security dolgok, cultireinfo meg ilyenek (utóbbit pl. .NET-ben thread szinten tudod állítani). Próbáltam még olyat is, hogy a Thread Exceptionnal áll le. Nos, akkor hótzicher, hogy felszabadul a memória, ugyanis az OS fogja eltakaríani (a teljes programmal együtt.) Ennyit a leakelő .NET-ről. |