Mi a szemétgyűjtés és hogyan befolyásolja a program teljesítményét? – CloudSavvy IT

Avatar Gadam | 2021.03.09. 25 Views 0 Likes 0 Ratings

25 Views 0 Ratings Rate it

[ad_1]

Shutterstock / Smit

A szemétgyűjtés számos nyelv jellemzője, például a C # és a Java. Míg a kézi memóriakezelés, például a C ++, meglehetősen gyors lehet, az automatikus szemétszállítás javítja a fejlesztők életminőségét. Fontos azonban megérteni a teljesítmény következményeit, ha a GC-t elhagyja a munkája.

Verem vs. Halom

Ahhoz, hogy megértse, mit csinál egy szemétgyűjtő, először meg kell értenie a különbséget a veremben tárolt memória és a kupacban tárolt memória között. Mindkettő speciális memóriahely a programhoz rendelt memóriában, a számítógép rendelkezésre álló RAM-jából.

A Kazal gyors, és rögzített bájtméretű értéktípusokhoz használják. Természetesen ugyanaz a fizikai memória, mint a kupac, csak gyors, mert nagyon rendezett First-In, Last-Out adatstruktúra. Amikor elkészít egy helyi változót, az eltárolja azt a veremben, és amikor a funkciója kilép, és a változó kilép a hatóköréből, automatikusan kitisztul a veremről.

Ez egy nagyon gyors folyamat, és alapvetően ingyenesvé teszi a veremkiosztásokat. Bár van teljesítménybüntetés, ez ugyanolyan olcsó, mint amennyi lesz.

A Halom, másrészt olyan nagy objektumokhoz használják, mint a listák és a karakterláncok, amelyek túl nagyok ahhoz, hogy a veremben tárolhatók legyenek, vagy amelyeket sokáig kell tárolni, miután a függvények kiléptek a hatókörből, amit a veremallokációk nem tudnak megtervezni. Bármikor new object, halom kiosztást hajt végre. Valószínűleg veremkiosztást is készít, mivel ha referenciát tárol egy helyi változóba, akkor azt a helyi változót létre kell hozni, hogy az az új objektum tényleges memóriájára mutasson.

A halomallokáció szintén lassabb, mint a veremallokáció.

A kupac meglehetősen lassabb, mind a memória lefoglalására, mind az eltávolításra. Ez minden, a modellt használó nyelvre vonatkozik, szemétgyűjtővel vagy anélkül.

A szemét takarítása

Természetesen ez nem olyan egyszerű, mint csak „egyszer elosztani és elfelejteni”. Ha soha nem távolítanánk el a memóriát, lenne egy memóriaszivárgás, ami nagyon rossz és gyorsan felemészti a gép RAM-ját. Az olyan felosztások, mint a helyi listák, azonnal kikerülnek az alkalmazási körből, de takarítás nélkül örökre eltömítenék a kupacot. Tehát a programoknak meg kell tudniuk tisztítani a már nem szükséges memóriát.

A kézi memóriakezelő nyelvekben, mint például a C ++, a memóriát kézzel kezelik. Kézzel kell felszabadítania a memóriát, és törölnie kell a már nem használt objektumokat, hivatkozás vagy mutató segítségével az adott objektum memóriahelyére. Bár ez rendkívül gyors lehet, nem szórakoztató kódolni, és memóriahibákhoz és kihasználásokhoz vezethet. Ez az egyik fő oka annak, hogy a C ++ -ot „kemény” programozási nyelvnek tekintik, amelyen tanulni és kódolni lehet.

A kézi kezelés alternatívája, ha a gép automatikusan megteszi helyetted. Ez az úgynevezett szemétszállítás.

A szemétgyűjtő egy háttérszálon fut, és rendszeresen átvizsgálja az alkalmazás halmát és veremét, és olyan objektumokat keres, amelyekre már nincs hivatkozás. Ez azt jelenti, hogy az objektum értéktelen, és biztonságosan eltávolítható a program befolyásolása nélkül.

Vegyük például a következő álkódot, amely létrehoz és „töröl” egy objektumot

object refToObject = new object();
refToObject = null;

Mivel refToObject már nem hivatkozik a new object() létrehozásakor a szemétszedő látni fogja, hogy az új objektum lóg, anélkül, hogy bárhonnan hivatkozna rá, és eltávolítja, amikor a következő alkalommal szemetet gyűjt.

A szemétszedő is elég okos, és képes megoldani a körkörös függőségeket. Például, ha két objektumod van, amelyek hivatkoznak egymásra, de semmi más nem tud róluk, az szemét. A legtöbb esetben, ha egy objektumnak nincs referencia lánca, amely a program gyökerétől indul, és az objektumhoz vezet, az szemét.

A szemétszállítás bármikor kiváltható, általában:

  • Ha a rendszerben kevés a memória.
  • A halom memóriájának százaléka meghaladja egy bizonyos küszöböt. Ezt a küszöbértéket automatikusan beállítják, és alapvetően akkor történik, amikor a GC úgy látja, hogy a programot tisztítani kell.
  • Amikor manuálisan kiváltja, mint például GC.Collect().

Hatások a teljesítményre

Természetesen a szemétszállítás egyáltalán nem ingyenes. Ha lenne, akkor minden nyelv használná. A GC lassú, főleg azért, mert szüneteltetnie kell a program végrehajtását a szemétgyűjtéshez.

Gondoljon így: a CPU egyszerre csak egy dolgon tud dolgozni. A C ++ esetén mindig dolgozik a kódodon, beleértve a memóriát törlő biteket is. GC esetén a program nem törli a memóriát, és addig fut, amíg szemetet nem keletkezik. Ezután szünetel, és a CPU a szemétszállítással foglalkozik. Ha ezt gyakran teszi, ez lelassíthatja az alkalmazások teljesítményét.

Általában ez meglehetősen gyors, általában kevesebb, mint néhány milliszekundum. A .NET esetében ez attól függ, hogy milyen típusú memóriát takarítanak meg, mivel nyomon követi a memóriát a különböző „generációkban”:

  • 0. generáció, a legfiatalabb generáció, amely rövid élettartamú objektumokat, például ideiglenes változókat tartalmaz.
  • 1. generáció, amely pufferként működik rövid és hosszú távú objektumok között. Ha egy objektum túlél egy szemétszedési kísérletet, akkor egy magasabb generációvá „népszerűsítik”.
  • 2. generáció, az utolsó, amely hosszú távú objektumokat követ.

A GC ellenőrzi az objektumokat a Gen0-ban, majd a Gen1-ben, majd a Gen2-ben. Mivel csak ideiglenes vagy újonnan létrehozott objektumokat tartalmaznak, a Gen0 és Gen1 tisztítása általában elég gyors, de a Gen2 sok memóriát tartalmaz. A „teljes szemétszállítás” elvégzése sokkal lassabb lehet, mint az elmúló szemétszállítás.

Hogyan lehet felgyorsítani a teljesítményt?

Tehát mit tehet ennek megakadályozása érdekében? Nos, a nap végén fel kell venni a szemetet. Az egyetlen igazi dolog, amit tehet, az, hogy csökkenti a program által dobott szemét mennyiségét.

A szemét csökkentésének egyik fő módja a hasznosítás Objektumok összevonása. Ennek alapelve az, hogy gyakran gyorsabb az objektumok alapértelmezettre állítása, mint egy újat készíteni és a régit kidobni.

Például a következő kód 10 ezerszer ismétlődik, és minden alkalommal új listát készít, hogy tegyen vele valamit. Ez azonban szörnyű a GC-n, ezért jobb módszer egy nagy listát készíteni, és törölni, miután végzett vele, és újat akar.

Ez a kód 10 000-szer fog futtatni, és 10 000 tulajdonos nélküli listát hagy a memóriában a funkció végén.Futtassa az új listát a ciklus előtt az első kiosztás elvégzéséhez, majd futtassa .Törölje vagy állítsa alaphelyzetbe az adatokat a memóriaterület és a keletkezett szemét megtakarítása érdekében.

A gyakorlatban ez általában egy általános „Object Pool” -val történik, amely kezeli az objektumok listáját, amelyeket „kibérelhet” a programjának. Amikor a kód elkészült, az objektumot visszaszabadítja a készletbe, és alaphelyzetbe állítja, készen áll arra, hogy kérésre újra felhasználható legyen.

[ad_2]
Source link