[Delphi 8.NET] ruimt de garbage collector mijn instance op ?

Pagina: 1
Acties:
  • 111 views sinds 30-01-2008
  • Reageer

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:29
procedure TWinForm1.Button1_Click(sender: System.Object; e: System.EventArgs);
begin
TestClass := TTestClass.Create;

TestClass.SayHello;
end;

TestClass is maar een dummy lege class met een method 'SayHello'. Als ik deze code in een buttonclick hang, zorgt de garbage collector van .NET er voor dat deze instance op den duur vrij wordt gegeven ? In de niet .NET periode moest je zelf voor TestClass.Free zorgen.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
De garbage collector zorgt ervoor dat alle niet langer gereferencete objecten vrijgegeven worden. Wanneer dat gebeurt kan je echter niet weten.

Als je echter zelf weet dat je je object op een bepaald punt niet meer nodig hebt, en je wilt dat de resources vrijgegeven worden, kan je de Dispose method van dat object gaan aanroepen.
In die dispose method schrijf je dan de code om de resources vrij te geven.

[ Voor 48% gewijzigd door whoami op 05-02-2004 13:32 ]

https://fgheysels.github.io/


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:29
whoami schreef op 05 februari 2004 @ 13:31:
De garbage collector zorgt ervoor dat alle niet langer gereferencete objecten vrijgegeven worden. Wanneer dat gebeurt kan je echter niet weten.
ja dat snap ik, heb zelf al heel wat over het framework gelezen. Echter, alle voorbeelden zijn voor C#, maar ik vraag me af of mijn code ook zo richting de garbage collector gaat. Als ik de IDipose interface implementeer komt de debugger daar namelijk niet terecht!

  • Schmoove
  • Registratie: Juli 2001
  • Laatst online: 22:53
Als je iets dynamisch aanmaakt is het gebruikelijk om het ook weer netjes op te ruimen. Dus ik zou toch maar gewoon de Free functie gebruiken.

EDIT:
Bijvoorbeeld als je gigantische blokken geheugen gaat reserveren en je programma draait in de achtergrond dan ben je dus afhankelijk van die garbage collector..... en je weet niet wanneer hij je rotzooi opruimt. Als je na gebruik gewoon netjes Free doet, dan blijft je programma ook niet onnodig geheugen gebruiken.

[ Voor 54% gewijzigd door Schmoove op 05-02-2004 13:35 ]


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:29
Schmoove schreef op 05 februari 2004 @ 13:33:
Als je iets dynamisch aanmaakt is het gebruikelijk om het ook weer netjes op te ruimen. Dus ik zou toch maar gewoon de Free functie gebruiken.
in Delphi 7 en lager misschien, maar deze .exe of .dll is puur .NET, is het dan nodig om expliciet .Free aan te roepen ?

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:27

Creepy

Tactical Espionage Splatterer

DrDelete schreef op 05 februari 2004 @ 13:34:
[...]


in Delphi 7 en lager misschien, maar deze .exe of .dll is puur .NET, is het dan nodig om expliciet .Free aan te roepen ?
Waarom zou je het niet doen als je toch al weet dat je het object niet langer nodig hebt?

En hoe weet de carbage collectorin jou voorbeeld wanneer die TestClass niet meer in gebruik is? Wat is de scope van dat ding? (dat heb je niet aangegeven, maar ik ga nu even uit van een global scope).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:29
Creepy schreef op 05 februari 2004 @ 13:46:
[...]

Waarom zou je het niet doen als je toch al weet dat je het object niet langer nodig hebt?

En hoe weet de carbage collectorin jou voorbeeld wanneer die TestClass niet meer in gebruik is? Wat is de scope van dat ding? (dat heb je niet aangegeven, maar ik ga nu even uit van een global scope).
zie: http://bdn.borland.com/article/0,1410,29365,00.html

daaruit maak ik op dat ik zelf instances kan maken, zodat de garbage collector van .NET zelf de boel opruimt. Nu weet ik alleen niet of wijze waarop ik dat deed (op de "oudewetse" manier) geldig is, of dat ik via een instance-factory moet werken...

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ja, in D8 gaat het netzoals in C# en heb je dus een GC. Nee, je hoeft je objecten niet meer expliciet vrij te geven met Free. Delphi's TObject implementeerd standaard IDisposable en de Free functie maakt daar gebruik van. Het kan dus geen kwaad alsnog Free aan te roepen, maar het hoeft niet.

We adore chaos because we like to restore order - M.C. Escher


Verwijderd

Creepy schreef op 05 februari 2004 @ 13:46:
Waarom zou je het niet doen als je toch al weet dat je het object niet langer nodig hebt?
Omdat het in de praktijk niet altijd even simpel is als dit voorbeeld.
En hoe weet de carbage collectorin jou voorbeeld wanneer die TestClass niet meer in gebruik is? Wat is de scope van dat ding? (dat heb je niet aangegeven, maar ik ga nu even uit van een global scope).
En daar gebruiken we nu reference counting voor. Zodra de reference count op 0 staat kan deze opgeruimd worden.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Verwijderd schreef op 05 februari 2004 @ 15:23:
[...]
En daar gebruiken we nu reference counting voor. Zodra de reference count op 0 staat kan deze opgeruimd worden.
Ik dacht dat de .NET GC geen reference counting gebruikt, maar mark en collect. De GC gaat er vanuit dat alle objecten garbage zijn.
Phase I: Mark
Find memory that can be reclaimed.

When the garbage collector starts running, it makes the assumption that all objects in the heap are garbage. In other words, it assumes that none of the application's roots refer to any objects in the heap.

The following steps are included in Phase I:

The GC identifies live object references or application roots.
It starts walking the roots and building a graph of all objects reachable from the roots.
If the GC attempts to add an object already present in the graph, then it stops walking down that path. This serves two purposes. First, it helps performance significantly since it doesn't walk through a set of objects more than once. Second, it prevents infinite loops should you have any circular linked lists of objects. Thus cycles are handles properly.
Once all the roots have been checked, the garbage collector's graph contains the set of all objects that are somehow reachable from the application's roots; any objects that are not in the graph are not accessible by the application, and are therefore considered garbage.

Phase II: Compact
Move all the live objects to the bottom of the heap, leaving free space at the top.

Phase II includes the following steps:

The garbage collector now walks through the heap linearly, looking for contiguous blocks of garbage objects (now considered free space).
The garbage collector then shifts the non-garbage objects down in memory, removing all of the gaps in the heap.
Moving the objects in memory invalidates all pointers to the objects. So the garbage collector modifies the application's roots so that the pointers point to the objects' new locations.
In addition, if any object contains a pointer to another object, the garbage collector is responsible for correcting these pointers as well.
After all the garbage has been identified

https://fgheysels.github.io/


Verwijderd

Schmoove schreef op 05 februari 2004 @ 13:33:
Bijvoorbeeld als je gigantische blokken geheugen gaat reserveren en je programma draait in de achtergrond dan ben je dus afhankelijk van die garbage collector..... en je weet niet wanneer hij je rotzooi opruimt. Als je na gebruik gewoon netjes Free doet, dan blijft je programma ook niet onnodig geheugen gebruiken.
dit klopt niet, .Free is een lege operatie in D8, die alleen voor backward compatibility is. .Free ruimt niets op, dat doet de garbage collector altijd

[edit]
Schmoove schreef op 05 februari 2004 @ 13:33:
Bijvoorbeeld als je gigantische blokken geheugen gaat reserveren en je programma draait in de achtergrond dan ben je dus afhankelijk van die garbage collector..... en je weet niet wanneer hij je rotzooi opruimt.
dat klopt, maar de garbage collector ruimt altijd op als je een grote allocatie gaat doen, of als er onvoldoende geheugen vrij is.

[ Voor 29% gewijzigd door Verwijderd op 05-02-2004 15:54 ]


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
whoami schreef op 05 februari 2004 @ 15:46:
Ik dacht dat de .NET GC geen reference counting gebruikt, maar mark en collect. De GC gaat er vanuit dat alle objecten garbage zijn.
Reference counting is no-way te implementeren met circular references.
De gebruikelijke term is trouwens mark and sweep, vaak gecombineerd met een stop and copy in de sweep fase.

Globaal zit het zo:
- De heap is opgedeeld in twee delen: A en B

• Mark: Vanaf de stack alle verwijzingen af gaan. De objecten die je dan tegen komt, die worden als alive gemarkeerd
• Stop: Stop het programma tijdelijk
• Copy: Copieer alle live objects van A naar B, zodanig dat je een gedefragmenteerde heap hebt

Vaak switched het programma (adaptive collectors) van 'stop & copy mark and sweep' naar 'echte' mark and sweep als het programma stabiel is en er niet zo veel objecten meer bijkomen.

Optimalisatie hierin, omdat je nu de hele tijd objecten copieert die in de globale scope zitten en niet gedestruct worden, is om de heap verder te verdelen in sub-heaps waar je verschillende 'generaties' objecten houdt. Een generatie is dan een object die een x aantal rondes GC heeft overleefd.

Affijn: http://glimi.dezeserver.nl/GarbageCollection(Eng).pdf en http://www.artima.com/insidejvm/ed2/gc.html
Creepy schreef op 05 februari 2004 @ 13:46:
Waarom zou je het niet doen als je toch al weet dat je het object niet langer nodig hebt?
Garbage collect runt pas als het nodig is. Vaak is het helemaal niet nodig om te runnen in een programma om het een stabiel aantal MB's geheugen gebruikt. Juist die tijd die het de-alloceren dan kost (wat soms best lang kan zijn!) bespaar je dan, omdat die dan bij het opruimen aan het einde van de lifetime van het programma gedaan worden

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:27

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 05 februari 2004 @ 15:23:
[...]

Omdat het in de praktijk niet altijd even simpel is als dit voorbeeld.

[...]

En daar gebruiken we nu reference counting voor. Zodra de reference count op 0 staat kan deze opgeruimd worden.
Dan blijft natuurlijk de vraag hoe de reference count naar beneden wordt gehaald. Oftewel: Wanneer is een object niet meer geldig, of hoe weet het systeem dat (dit nogmaals in het licht van het aangehaalde voorbeeld, waar het een globale variabele lijkt).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Verwijderd schreef op 05 februari 2004 @ 15:51:
dit klopt niet, .Free is een lege operatie in D8, die alleen voor backward compatibility is. .Free ruimt niets op, dat doet de garbage collector altijd
Toch wel...

Hieronder een stukje code uit TObject.Free van D8. TObjectHelper is een trukje/hack om functies toe te voegen aan een reeds bestaande class.
Delphi:
1
2
3
4
5
6
7
8
9
procedure TObjectHelper.Free;
begin
  if (Self <> nil) and (Self is IDisposable) then
  begin
    if Assigned(VCLFreeNotify) then
      VCLFreeNotify(Self);
    (Self as IDisposable).Dispose;
  end;
end;

We adore chaos because we like to restore order - M.C. Escher


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Creepy schreef op 05 februari 2004 @ 16:03:
Dan blijft natuurlijk de vraag hoe de reference count naar beneden wordt gehaald. Oftewel: Wanneer is een object niet meer geldig, of hoe weet het systeem dat (dit nogmaals in het licht van het aangehaalde voorbeeld, waar het een globale variabele lijkt).
Als je variabele opgeruimd kan worden in je programma, dan hoeft hij geen globale scope te hebben is het niet?
Tevens kun je, als je er vanaf wilt, de reference gewoon op null/nil zetten. Dan gaat hij daarna wel met de GC mee (na 2x collect)

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
DrDelete schreef op 05 februari 2004 @ 13:33:
[...]


ja dat snap ik, heb zelf al heel wat over het framework gelezen. Echter, alle voorbeelden zijn voor C#, maar ik vraag me af of mijn code ook zo richting de garbage collector gaat. Als ik de IDipose interface implementeer komt de debugger daar namelijk niet terecht!
De Dispose gebruik je om expliciet aan te geven dat je de resources van het object wilt vrijgeven. Je roept dus zelf de Dispose expliciet aan.
Als de GC objecten gaat gaan vrijgeven, roept hij niet de Dispose aan, maar de Finalizer.

https://fgheysels.github.io/


Verwijderd

LordLarry schreef op 05 februari 2004 @ 16:05:
[...]

Toch wel...

Hieronder een stukje code uit TObject.Free van D8. TObjectHelper is een trukje/hack om functies toe te voegen aan een reeds bestaande class.
Delphi:
1
Delphi:
1
2
3
4
5
6
7
8
var
  a:TIets;
begin
  a:=TIets.Create;
  a.Free;
  a.DoIets; // dit mag, want a is nog niet vrijgegeven, 
                  //omdat er nog een referentie naar de instantie is
end.

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:29
Glimi schreef op 05 februari 2004 @ 16:02:
[...]

Reference counting is no-way te implementeren met circular references.
De gebruikelijke term is trouwens mark and sweep, vaak gecombineerd met een stop and copy in de sweep fase.

<knip>
aardig verhaal Glimi. Ik heb me niet volledig verdiept in het GC verhaal, maar kun je me ff uitleggen wat een heap en stack is :D

In Delphi is de stack via stacktrace te volgen en behelst de aanroepgeschiedenis. Wat voor relatie hebben heap en stack dan met elkaar tov GC ?

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Wat staat er op een heap ?
Het geheugen dat je gealloceerd hebt.
Wat moet je vrijgeven?
Het gealloceerde geheugen dat niet meer nodig is.

https://fgheysels.github.io/


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 23:27

Creepy

Tactical Espionage Splatterer

Glimi schreef op 05 februari 2004 @ 16:08:
[...]

Als je variabele opgeruimd kan worden in je programma, dan hoeft hij geen globale scope te hebben is het niet?
Ik doel nog steeds op het stukje code in de topic start. Wat is nu de scope van die variabele., en hoe gaat de GC daar mee om? (lees: nog niemand heeft verteld wat de scope is van die specifieke variabele, en de TS heeft dat ook nog steeds niet gemeld ;) ).

Met een stukje code als
Delphi:
1
2
3
4
5
6
procedure blaat;
var woei: TMyClass
begin
  woei:=TMyClass.create;
  woei.blaat;
end;

is dat WEL duidelijk.

Of ben ik nu echt aan het muggenziften

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
DrDelete schreef op 05 februari 2004 @ 16:21:
(...)maar kun je me ff uitleggen wat een heap en stack is :D
In Delphi is de stack via stacktrace te volgen en behelst de aanroepgeschiedenis. Wat voor relatie hebben heap en stack dan met elkaar tov GC ?
Een stack is een LIFO container. Stel het je voor als een stapel. Elke keer kun je alleen het bovenste ding eraf halen. De stack wordt dan ook gebruikt om telkens de method/functie waar je in zit op te slaan en daarbij de bijbehorende variabelen (references en primitieven). Dus behalve je 'aanroepgeschiedenis' kun je ook alle variabelen vinden die je 'direct' kunt bereiken op je stack

De Heap kun je je voorstellen als een plek waarin het geheugen staat voor de objecten die je aanmaakt. Verwar dit niet met de datastructuur 'heap', want dit is iets totaal anders :)

Als de GC gaat draaien, gaat hij er in eerste instantie van uit dat alles garbage is. Maar hoe vindt hij dat alle objecten die je nog wel kunt bereiken? Op de stack stonden alle references naar objecten die we 'direct' konden bereiken. Als we die references volgen, komen we bij objecten op de heap. Deze objecten kunnen zelf ook referenties bevatten naar objecten, dus die volgen we ook, totdat we geen nieuwe objecten meer tegenkomen. Dan hebben we alle levende objecten gevonden en ruimen we de rest op.
Creepy schreef op 05 februari 2004 @ 16:32:
Ik doel nog steeds op het stukje code in de topic start. Wat is nu de scope van die variabele., en hoe gaat de GC daar mee om?
Nee, jij deed de aanname dat het globale scope was ( 6de post ) en daar is mijn antwoord dan ook op gebaseerd.

[ Voor 13% gewijzigd door Glimi op 05-02-2004 16:41 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:00

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik heb het verder nog niemand zien zeggen, dus doe ik het maar even :Y)
DrDelete schreef op 05 februari 2004 @ 13:33:

ja dat snap ik, heb zelf al heel wat over het framework gelezen. Echter, alle voorbeelden zijn voor C#, maar ik vraag me af of mijn code ook zo richting de garbage collector gaat. Als ik de IDipose interface implementeer komt de debugger daar namelijk niet terecht!
De garbage collector is niet van C#, maar van .net, het onderliggende platform dus. Als je in C# je objecten niet op hoeft te ruimen betekent dat dat je dat in elke .net taal niet hoeft te doen, .net zorgt hier namelijk zelf voor

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Verwijderd schreef op 05 februari 2004 @ 16:19:
Delphi:
1
2
3
4
5
6
7
8
var
  a:TIets;
begin
  a:=TIets.Create;
  a.Free;
  a.DoIets; // dit mag, want a is nog niet vrijgegeven, 
                  //omdat er nog een referentie naar de instantie is
end.
Is het "Mag" of "geeft geen exceptie"? Ik heb nog weinig verstand van .Net op dat gebied, maar TObject implementeerd IDisposable en in de Free wordt weldegelijk IDispose.Dispose aangeroepen. Of na de Dispose ook echt het object weg is of dat ie alleen aangemerkt is om op te ruimen. Als dat het geval is kan de code van jouw misschien wel werken, maar is het een potentiele bug. Als de Dispose niets van dit alles doet zou je code wel correct zijn, maar dan zie ik het nut van Dispose niet zo in.

We adore chaos because we like to restore order - M.C. Escher


  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
LordLarry schreef op 06 februari 2004 @ 09:41:
[...]

Is het "Mag" of "geeft geen exceptie"? Ik heb nog weinig verstand van .Net op dat gebied, maar TObject implementeerd IDisposable en in de Free wordt weldegelijk IDispose.Dispose aangeroepen. Of na de Dispose ook echt het object weg is of dat ie alleen aangemerkt is om op te ruimen. Als dat het geval is kan de code van jouw misschien wel werken, maar is het een potentiele bug. Als de Dispose niets van dit alles doet zou je code wel correct zijn, maar dan zie ik het nut van Dispose niet zo in.
Normaal gezien zou er een 'object is disposed' exception moeten optreden als je een disposed object aanspreekt (het object is niet null, maar IsDisposed is wel true).
Wel logisch dat er een exceptie optreedt, want Dispose geeft de resources van dat object vrij, de goede werking kan je dus niet meer garanderen.

[ Voor 9% gewijzigd door whoami op 06-02-2004 09:53 ]

https://fgheysels.github.io/

Pagina: 1