1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.

Slides:



Advertisements
Hasonló előadás
Sor láncolt ábrázolással
Advertisements

Osztály leszármaztatás
Programozási tételek, és „négyzetes” rendezések
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
C++ programozási nyelv Gyakorlat hét
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Objective-C Memória kezelés
Öröklődés 2..
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Dinamikus tömbök.
Fájlkezelés, IO Kivételkezelés Belső osztályok
Osztályok Garbage collection.  általában minden osztálynak vannak adattagjai és/vagy metódusai ◦ adattagok megadása:  [láthatóság] [static] [final]
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 5. Gyakorlat Öröklődés, virtuális függvények,
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A Java programozási nyelvSoós Sándor 1/17 Java programozási nyelv 4. rész – Osztályok II. Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai.
Java programozási nyelv 3. rész – Osztályok I.
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/12 C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
C# tagfüggvények.
C# tagfüggvények.
8. előadás Dinamikus memóriakezelés. Mutatók. Láncolt adatszerkezetek.
1 Operációs rendszerek Az ütemezés megvalósítása.
P ROGRAMOZÁS C# - BAN Kivételkezelés. P ÉLDA I. Nullával való osztás miatt kapjuk a hibaüzenetet.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
V 1.0 Szabó Zsolt, Óbudai Egyetem, Programozási Paradigmák és Technikák Programozási eszközök Interfészek Generikus.
V 1.0 Szabó Zsolt, Óbudai Egyetem, Programozási Paradigmák és Technikák Programozási eszközök Interfészek Generikus.
Rekordok Dinamikus tárkezelés és pointerek Dinamikusan láncolt listák
Java programozási nyelv Metódusok
Programozás III UNIT TEST. És tényleg: Honnan lehet tudni, hogy működik-e vagy sem?
Objektum orientált programozás
1 Objektum orientált programozás Öröklődés: többszörös öröklődés, konstruktorok, destruktorok, overloading Nagy Szilvia.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Gráfok ábrázolása teljesen láncoltan
Objektumorientált alapjai ISZAM III.évf. részére Bunkóczi László.
CUDA C/C++ programozás CUDA C bevezetés A segédanyag készítése a TÁMOP A/ Nemzeti Kiválóság Program című kiemelt projekt keretében.
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
a programegységek között
A C++ programozási nyelv
Hernyák Zoltán Programozási Nyelvek II.
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Hernyák Zoltán Programozási Nyelvek II.
Előadás másolata:

1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz

2 A konstruktor-ok a példány használata előtt hívódnak meg, a példány életciklusának elején. A destruktorok olyan speciális metódusok, amelyek az életciklus végén hívódnak meg. A destruktorokban a példány megszűnése előtti ‘nagytakarítás’-t kell elvégezni:  pluszban foglalt memória felszabadítása  megnyitott file-ok lezárása  nyomtatás befejezésének jelzése  hálózati kapcsolatok lezárása  stb…

3 A destruktorok neve kötelezően megegyezik az osztály nevével, de előtte egy ~ jel kell szerepeljen! class TFtpKliens { ~TFtpKliens() { // hálózati kapcsolatok lezárása... } class TFtpKliens { ~TFtpKliens() { // hálózati kapcsolatok lezárása... } A destruktornak nem lehet elérési szint módosítója (automatikusan public)! A destruktornak nem lehet paramétere sem! Ezért minden osztályhoz maximum 1 db destruktort készíthető!

4 Miért ez a sok megkötés a destruktorra? (#1) Történelmileg a destruktort először a programozók hívták meg explicit módon, valami hasonló módon: TVerem v = new TVerem(); … // v példány használata free v ~TVerem(); TVerem v = new TVerem(); … // v példány használata free v ~TVerem(); A destruktort hívásakor szabadítódott fel a példányhoz tartozó memóriaterület is. Ha a programozó ‘elfelejtette’ ezt meghívni, akkor a példány ottragadt a memóriában, és memóriaszivárgás (memory leak) keletkezett. Az ilyen program ha sokáig futott a memóriában, akkor elég sok idő után a teljes memóriát ilyen ‘beragadt’, haszontalan példányok foglalták el. ( ez egyébként nem működik C#-ban !!!!

Tipikus hibák:  A programozó ‘elfelejti’ meghívni a felszabadítást. Ekkor a példány ottragadt a memóriában, és memóriaszivárgás (memory leak) keletkezett. Az ilyen program ha sokáig futott a memóriában, akkor elég sok idő után a teljes memóriát ilyen ‘beragadt’, haszontalan példányok foglalták el.  A programozó rosszkor (idő előtt) hívta meg a felszabadítást, a példányra még van hivatkozás. a = peldany; b = a; // b is ugyanarra a példányra mutat free a; // a példány eltűnik a memóriából b.muvelet(); // ez itt hiba forrása már a = peldany; b = a; // b is ugyanarra a példányra mutat free a; // a példány eltűnik a memóriából b.muvelet(); // ez itt hiba forrása már Ekkor a program ‘bármit’ is csinálhat… de jót ritkán

6 (#2) Erre megoldást nyújtott a referencia típusú változó: Ennek során a futtató rendszer nyilvántartotta nemcsak azt, hogy hol vannak a példányok számára lefoglalt memóriaterületek, hanem azt is, hogy hány változó hivatkozik az adott példányra. ( referenciaszámlálás elve ) - Amikor egy példány memóriaterületét egy változóba értékül adjuk, akkor a referenciaszámláló növelődik 1-el. -Amikor egy ilyen változó másik értéket kap, vagy megszűnik, akkor a referenciaszámláló csökken 1-el. -Amikor egy példányhoz tartozó referenciaszámláló eléri a 0-t, akkor automatikusan fel lehet szabadítani a hozzá tartozó memóriaterületet.

7 public int Akarmi() { TVerem v = new TVerem(); // v használata... } public int Akarmi() { TVerem v = new TVerem(); // v használata... } Példány memória allokálása Referenciaszámláló = 1 A lokális ‘v’ változó megszűnik létezni Referenciaszámláló = 0 Példány törlése a memóriából automatikusan! A példány törlése során 1: meg kell hívni a destruktorát, hogy ‘éretsítődjön’ a példány, hogy törlése fog kerülni, amit még akar az ‘utolsó szó jogán’ azt tegye meg 2: a lefoglalt memória felszabadítása

8 Az ilyen referenciaszámlálás-elvű programozási nyelveken a destruktort már nem explicit módon hívja meg a programozó, hanem a futtató rendszer hívja meg automatikusan (implicit). A futtató rendszer viszont nem fog neki paramétert átadni (nem is tudna honnan), ezért itt már nincs értelme a destruktort paraméteresen megírni (nem is szabad).

9 A referenciaszámlálás nem okoz komolyabb mérvű lassulást a program futása során! Ugyanakkor a programozók azonnal megszerették, mert megszűnt a memóriaszivárgás, egyszerűsödött a program írása, egy hibalehetőség megszűnt (egy gonddal kevesebb). Ugyanakkor jegyezzük meg, hogy a referenciaszámlálás bonyolultabb esetben sajnos egyszerűen semmit sem ér  !

10 Tegyük fel, hogy egy A példány hivatkozik egy B példányra, és a B is hivatkozik az A példányra ( kölcsönös hivatkozás ). Ilyenek pl. a ciklikusan láncolt lista elemei! ”A” példány ”B” példány változó = ”A” példány; Referenciaszámláló = 2 Referenciaszámláló = 1

11 Ha a változó megszűnik, vagy már nem erre a példányra hivatkozik, akkor az ”A” példány a programból már elérhetetlenné vált. Ugyanakkor a referenciaszámlálója még mindig 1! ”A” példány ”B” példány változó = null; Referenciaszámláló = 1 Ekkor az ”A” és a ”B” példány is beragadt a memóriában! Pedig ezt akartuk kikerülni…

12 (#3) Egy komolyabb programban a példányok egymásra is hivatkoznak, és ez egy komoly hivatkozási hálót ( gráfot ) hoz létre. Egy egyszerű referencia számlálás kevés a felesleges példányok felfedezésére és kiszűrésére. a program ‘élő’ változói hivatkoznak a példányokra a program ‘élő’ változói hivatkoznak a példányokra

13 A megoldás, hogy a gráfot be kell járni (gráfbejáró algoritmussal, pl szélességi vagy mélységi bejárás) a program változóiból kiindulva. Amely példányhoz nem lehet eljutni az élek ( hivatkozások ) mentén, azok a példányok feleslegesek, és ki lehet őket törölni. Ezt a megvalósítást már nem referencia-számlálásnak nevezzük, hanem ‘szemétgyüjtésnek’. Szemét = garbage Gyűjtő = collector

Obj1 NextObjPtr Amikor új példányt hozunk létre, akkor egy halom (heap) területen lefoglalunk egy egybefüggő szakaszt. Ezen területen az első szabad helyet egy változó jelöli, őt kell növelni a lefoglalandó terület méretével:

Gyökerek Aztán jön a GC, elemzi a hivatkozási gráfot, és kiszúrja a felesleges példányokat. A gyökerek a program aktuálisan élő változói: NextObjPtr Obj4 Obj3 Obj2 Obj1 1. Gyökerek 2. Elérhetőségi gráf 3. Takarítás 4. Tömörítés 5. Mutatók frissítése

16 Ha a futtató rendszer GC-t használ, akkor a destruktort hívása automatikusan történik meg, amikor eljut odáig a GC. Ez általában nem azonnal történik meg, mint ahogy a példány ‘szemétté’ válik, időre van szükség. Ezért a destruktort hívásának időpontja nemdeterminisztikus. Az sem determinisztikus, hogy az ”A” vagy a ”B” példányra hívódik-e meg először a destruktor, és szabadítódik fel a memória. ”A” példány ”B” példány

17 C#-ban a destruktort a programunkkal párhuzamosan, egy külön szálon fut. Másodpercenként több száz millió példányt képes felfedezni, és felszabadítani ha kell. Valamelyest lassítja a program futását, de ez elhanyagolható azon előny mellett, hogy garantáltan nincs memóriaszivárgás a programban, és a programozó nem véthet ilyen jellegű hibát. Pl: egy GC-vel ellátott nyelven a láncolt lista minden elemének törlése: A többit a GC végzi FejElem = null;

18 Nagyon ritkán írunk destruktort, mert: - a pluszban lefoglalt memória is példány, és a GC majd azt is fel fogja szabadítani - a hálózati kapcsolat létrehozásához is példányosítani kell egy ‘hálózati kapcsolat’ osztályt, és ezen példányt a GC meg fogja találni, és meghívja rá az ő destruktorát, és akkor a hálózati kapcsolat automatikusan lezárja magát stb… Ezért csak nagyon speciális esetben kell nekünk magunknak explicit módon felszabadítani erőforrást.

19 Valójában a C#-ban nincs is destruktor, csak destruktornak kinéző metódus. A destruktor szót egyéb OOP nyelvekből vette át a C#. A destruktort valójában a Finalize() metódus override-ja. class TSajat { ~TSajat() {... } } class TSajat { ~TSajat() {... } } class TSajat { protected override Finalize() {... } class TSajat { protected override Finalize() {... }

20 A C# fordítóprogramja a destruktorunkat automatikusan Finalize()-nek olvassa. De nem engedi meg, hogy közvetlenül a Finalize-t definiáljuk felül. Ha az ős osztálynak is van destruktora, akkor az le fog futni, mielőtt a mi destruktorunk elindulna hasonlóan a konstruktorok hívási láncához.