Object destroyen

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 11:31

Hi,

wenn ich ein Objekt einer eigenen Klasse destroyen will, dann genügt es ja nicht das Objekt selbst auf NIL zu setzen. Es muß eine eigene destroy() Methode her. Das bedeutet doch, dass diese Destroy() Methode alle Memvars NILLEN muß. Was mache ich aber, wenn das etliche sind? Muß ich die alle einzeln angeben, oder könnte man sowas in einer Superklasse unterbringen, die dann mit entsprechenden Prüfungen alle Mebervars ermittelt und dann auf NIL setzt? Ich habe jetzt auf Anhieb nichts in der Anleitung gefunden, was mir da weiterhelfen könnte.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon brandelh » Mi, 14. Nov 2012 11:44

Hallo Manfred,

wegen eigenen Xbase++ Variablen (local, private) brauchst du kein destroy(), das macht der GC selbstständig.
Wenn du große Strings gespeichert hast, kannst du helfen indem du die auf NIL setzt.

destroy() braucht man nur wenn in create() Systemresourcen (Drucker, Fonts etc.) angefordert wurden.
Diese Systemresourcen würden sonst im Speicher bleiben und nur die Brücken dahin (Xbase++ Variablen) abgebrochen.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13494
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: Object destroyen

Beitragvon Jan » Mi, 14. Nov 2012 11:44

Wie allgemein bekannt bin ich ja kein Klassenmensch. Aber vielleicht ist das doch ein Denkansatz: Wenn ich gesammelt eine Gruppe von Objekten destroy()en möchte, dann mach ich das über oParent:childList(). Das zurückgegebene Array kann ich dann Position für Position abarbeiten. Manchmal destroy()e ich alle Children, manchmal nur die, die einem entsprechenden XBPart entsprechen. Was man ja ebenfalls abfragen kann.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
 
Beiträge: 11888
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 11:46

Hallo Hubert,

ich denke da in erster Linie an meinen Thread mit den GDI Objekten. Da hat der GC total versagt.

@Jan,

ich glaube Du hast da wieder was in den falschen Hals gekriegt.. :lol:
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon Jan » Mi, 14. Nov 2012 11:59

Manfred,

mag sein. Aber da Du im Eingangsbeitrag nicht exakt beschrieben hast, welche Arten von Objekten Du destroy()en willst, kam mir der Gedanke, das über den Parent-Weg versuchen zu können. Eventuell in Deinem Klassen-Denken mit anderen Methoden, aber vom Ansatz her ähnlich.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
 
Beiträge: 11888
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle

Re: Object destroyen

Beitragvon Tom » Mi, 14. Nov 2012 12:01

Ein Klassenobjekt, das irgendwo erzeugt wird, ist eine ganz normale Variable - und wird auch wie eine solche behandelt. Erzeuge ich das Klassenobjekt als LOCAL, verschwindet es am Ende der Funktion, dito bei PRIVATEs. Ich muss nix "nilen", erst recht nicht iVars oder so - das wäre auch hanebüchen. Ein Destroy() muss nur bei XbParts und davon abgeleiteten Objekten erfolgen, außerdem bei AutomationObjects. Dort erbt man aber die implizite Methode, so dass das automatisch passiert, wenn beispielsweise der Parent am Ende eines Dialogs zerstört wird. Man kann sie in solchen Fällen aber auch gezielt auslösen, wenn man auf Nummer sicher gehen will.
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6728
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 12:09

OK,

anders herum. In dem Thread über GDI Objekte ist klar geworden, das es Fälle gibt, in denen der GC total überfordert ist. Nachdem ich nun alles mögliche was ich finden konnte genillt hatte, sah die Sache schon wesentlich besser aus. Jetzt hatten wir gestern das Thema in Leverkusen und da kam der Hinweis, dass es nicht genügt, wenn ich meine eigenen Objekte einfach nur nille. Ich müßte da schon ein destroy einbringen, welches alle Membervars nillt usw., damit die im Objekt enthaltenen Membervars nicht irgendwo im Nirwana herumschwirren. Da es aber nicht vorhanden ist in den eigenen Klassen, muß diese Methode nachprogrammiert werden. Soweit so gut. Nun dachte ich dass man sowas pauschalisieren könnte, aber dem ist wohl nicht so.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon brandelh » Mi, 14. Nov 2012 12:18

Hallo Manfred,

lies doch mal die Beschreibung von NEW()/INIT(), CREATE() und DESTROY() nach.
NEW()/INIT() erzeugen die Xbase++ Variablen. Um die kümmert sich der GC normalerweise völlig selbständig.
CREATE() fordert nun vom Betriebssystem für XbpParts (Dialogfenster, Buttons, Fonts, Drucker, etc.) (GDI)-Resourcen an, falls du diese verwendest.
Wenn du solche verwendest, musst du diese auch in einer Methode DESTROY() wieder freigeben.
Wenn du Dateien öffnest, musst du diese ja auch wieder schließen.
Wenn du aber nur Arrays, Strings etc. hast, dann werden die automatisch aufgeräumt.

Es gibt aber Programme, die laden so nebenbei 200 MB in Stringvariablen und rufen die Funktion auch noch dauernd auf.
Hier KANN es dazu kommen, dass der GC nicht nachkommt und Probleme entstehen, die man beseitigen kann wenn man die riesigen Stringvars auf NIL setzt.
Man muss nicht, aber es hilft dem GC ;-)

Ansonsten ist es natürlich IMMER empfehlenswert für eigene Klassen ein DESTROY() zu definieren, auch wenn man nichts drinn macht.
So weiß der Anwender, dass man daran gedacht hat ;-)
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13494
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 12:25

Also irgendwie kommen wir nicht zu Kern der Sache.

Es ist vollkommen uninteressant, ob es notwendig ist oder nicht. Ich wollte nur wissen, ob sowas geht.

Allerdings könnte vielleicht hier schon direkt ein Abschluß getroffen werden: Wenn ich z.B. ein LOCAL Objekt aus einer eigenen Klasse erzeuge mit x iVars und dieses Objekt dann vor dem Verlassen der Funktion z.B. nur dieses Objekt auf NIL setze, wird dann alles was darin ist auch genillt, oder besteht die Gefahr, dss dann "Speichermüll" übrigbleibt. Vollkommen egal, ob es den GC gibt oder nicht. es geht nur um die reine Theorie. Deshalb habe ich mir die Gedanken dazu gemacht. Wenn alles andere auch genillt wird, dann hat sich meine Frage erübrigt.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon Tom » Mi, 14. Nov 2012 12:33

Destroy() gibt die Systemressourcen eines GDI-Objekts/XbParts wieder frei. Diese Methode macht überhaupt nichts mit den Instanzvariablen des Objekts; Du kannst es im vorigen Zustand restaurieren, einfach durch ein abermaliges Create(). Das hat mit Speicherauslastung o.ä. wenig zu tun. Destroy() verhindert lediglich, dass ein GDI-Objekt referenziert bleibt (nebst Children), das längst inaktiv ist. Wenn man ein solches Klassenobjekt löschen will, indem man ihm z.B. NIL zuweist, sollte es vorher zerstört werden.

Ein Objekt ist ansonsten mit einem Array zu vergleichen. Wenn ich a := {} mache oder aSize(a,0), werden - natürlich - auch alle Arrayelemente gelöscht. Genau dasselbe geschieht mit einem Objekt: Die Löschung des Objekts selbst führt selbstverständlich auch zur Löschung aller Instanzvariablen. Sonst wäre das ja haarsträubende Arbeit und eine originelle Version von OOP. Es dürfte auch schwer werden, die Instanzvariablen eines Objekts zu "nilen", das man selbst vorher insgesamt auf NIL gesetzt hat - schließlich existiert die Objektreferenz in diesem Augenblick nicht mehr. Das wäre auch der Fall, wenn man der Objektvariablen beispielsweise einfach einen numerischen Wert zuweisen würde. Ist unterm Strich dasselbe.
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6728
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 12:37

naja,

das man zuerst im Objekt selbst aufräumen muß und danach erst das Objekt nillt, dass ist mir schon klar. Deshalb habe ich es auch nicht ausdrücklich erwähnt. Und das andere ist mir auch klar. :roll: Also vorher destroy() und dann NIL
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon UliTs » Mi, 14. Nov 2012 12:42

Das Problem ist, dass LOCALs von Funktionen eben nicht immer vom Garbage Collector freigegeben werden können, wenn der Funktionsaufruf beendet wird!
Beispiel:
Code: Alles auswählen
FUNCTION GibMirEinenBloedenCodeBlock()
LOCAL A,B,C,D
  A := 10
  B := 20
  C := 30
  D := array( 100000 )
RETURN( {||A+B+C} )

In diesem Fall können die LOCALs A,B,C NICHT freigegeben werden, da sie ja im Codeblock verwendet werden!
Wenn so etwas vorkommt, werden meines Erachtens gleich ALLE LOCALs nicht freigegeben, also auch nicht D !
Und wenn diese Funktion ein paar 100000 mal aufgerufen wird, müßte es irgendwann knallen :happy10: :tongue2: :toothy3: :triplets:

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 2402
Registriert: Fr, 10. Feb 2006 10:51
Wohnort: Aachen

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 12:44

Ja,

das ist auch der letzte Rest, der noch übrigbleibt bei mir und für den ich keinen Ersatz wüßte. Darüber habe ich auch schon gegrübelt. :evil:
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon UliTs » Mi, 14. Nov 2012 12:47

Hast Du ein möglichst kurzes Beispiel, wo Du keine Idee für einen Ersatz hast?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 2402
Registriert: Fr, 10. Feb 2006 10:51
Wohnort: Aachen

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 12:51

z.B. diese simple Funktion, die ein False oder True zurückliefert. lErfolg kann ich ja nicht vorher nillen.....

Code: Alles auswählen
Function test()
             local lerfolg := .T.
             if nicht
                lerfolg := .F.
             endif
             return lErfolg
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon UliTs » Mi, 14. Nov 2012 12:53

Da brauchst Du auch nichts zu "nilen", da in Deinem Beispiel der Garbage-Collector "weiß", dass er alle LOCALs freigeben kann ...
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 2402
Registriert: Fr, 10. Feb 2006 10:51
Wohnort: Aachen

Re: Object destroyen

Beitragvon brandelh » Mi, 14. Nov 2012 12:53

Hallo Uli,

bist du dir bei deinem Beispiel sicher ?
Ich denke, dass D immer freigegeben wird, da auf D keine externen Verweise liegen.
Wie kann man das übrigens nachprüfen ?

Hallo Manfred,

bei deiner Funktion erübrigt sich jeder Gedanke ;-)
Als Ergebnis wird der WERT .t. oder .f. zurückgeliefert, die Variable lErfolg wird sauber entsorgt.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13494
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: Object destroyen

Beitragvon brandelh » Mi, 14. Nov 2012 13:01

Code: Alles auswählen
function MyUpper( cTxt ) // cTxt erhält eine Kopie des übergebenen Wertes und wird LOCAL
    local cX := upper(cTxt)
return cX       
cAltText := "abc"
cNeuText := MyUpper( cAltText )


Hier ist die Zuordnung nicht ganz so eindeutig. cX ist zwar LOCAL und wird als solche auch entsorgt, ist aber tatsächlich ja nur ein Zeiger auf den ASCIIZ String, der zugewiesen wurde.
Der Rückgabewert ist intern ein Pointer auf den tatsächlichen Text. cX wird also sauber entsorgt (der Pointer), der Text bleibt aber unter dem neuen Pointer (cNeuText) weiter erreichbar (wäre auch blöd wenn nicht ;-) ) ...

Aus diesem Grunde ist es sinnvoll nicht benötigte RIESIGE Texte mit "" oder NIL zurückzusetzen.
Der GC kann diese dann schneller freigeben. Das hat aber alles nichts mit den obenen genannten Resourcen zu tun, da hat Tom schon recht.

Sobald die EXE beendet wird, wird von der Runtime schon dafür gesorgt, dass alles (Speicher und Resourcen) wieder freigegeben werden.
Daher ist das Ganze auch nur wichtig, wenn die Funktion sehr oft aufgerufen wird bzw. das Programm im 24/7 Betrieb laufen soll.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
 
Beiträge: 13494
Registriert: Mo, 23. Jan 2006 21:54
Wohnort: Germersheim

Re: Object destroyen

Beitragvon Wolfgang Ciriack » Mi, 14. Nov 2012 13:06

Hallo Manfred,
wenn du trotzdem irgendetwas mit den Vars anfangen willst, könntest du vielleicht das nutzen:

Code: Alles auswählen
aVars:=obj:classDescribe(CLASS_DESCR_MEMBERS)
l:=len(aVars)
for i:=1 to l
     xName:=aVars[i, CLASS_MEMBER_NAME]
     xVal :=obj:&( aVars[i, CLASS_MEMBER_NAME] )
..........
Viele Grüße
Wolfgang
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 2245
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 13:07

Ja,

es werden alle Variablen entsorgt. Vom GC halt. Aaaber, was ist wenn sowas andauernd gemacht wird? Kommt der GC da noch mit auf die Dauer? Das Grundkonzept mit dem GC klappt ja auch. Nur nicht, wenn er stark gefordert wird. [-X

Ah Hubert hat noch einen nachgelegt, aber mit seinem letzten Satz genau ins Schwarze getroffen. Das ist das was ich als Problem hatte. Ich habe es jetzt allerdings ganz anders gelöst. Das Programm hat eh einen geplanten Tageswechsel, an dem was passiert und da rufe ich das Programm neu auf und beende das aktuelle. Mal sehen ob das eine Lösung ist mit der man leben kann.

Grr, Wolfgang kam auch noch dazwischen.

Das hatte ich auch mal kurz gelesen, aber so verstanden, dass das alles nur für dynamische Klassen gelten sollte.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 13:12

Hi Wolfgang,

das werde ich mir mal näher ansehen. Wenn das damit klappt, wäre es genau das was ich suchen würde. Das hatte ich doch total übersehen. ich war woanders drin was auch Class hieß.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Re: Object destroyen

Beitragvon UliTs » Mi, 14. Nov 2012 13:17

brandelh hat geschrieben:Hallo Uli,

bist du dir bei deinem Beispiel sicher ?
Ich denke, dass D immer freigegeben wird, da auf D keine externen Verweise liegen.
Wie kann man das übrigens nachprüfen ?

Ich bin mir ziemlich sicher, dass der Garbage Collector das zwar theoretisch könnte, praktisch aber nicht kann (=entsprechend intelligent programmiert ist) :-) :-( .
Ich meine, dass hatte Steffen mal selbst gesagt!
-
Von Dir so eine Frage: "Wie kann man das nachprüfen"? 8)
Ich würde sagen, ein Testprogramm schreiben :) Mir fehlt aber im Moment die Zeit, aber Du .....?
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 2402
Registriert: Fr, 10. Feb 2006 10:51
Wohnort: Aachen

Re: Object destroyen

Beitragvon Tom » Mi, 14. Nov 2012 13:28

cX ist zwar LOCAL und wird als solche auch entsorgt, ist aber tatsächlich ja nur ein Zeiger auf den ASCIIZ String, der zugewiesen wurde.


Wer erzählt denn so was?
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6728
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Object destroyen

Beitragvon Tom » Mi, 14. Nov 2012 13:53

Ich erinnere mich, dass SP beim Forentreffen oder bei der DevCon zugesagt hatte, Alaska wolle gelegentlich ins Forum schauen, um dann via Verein bei Threads zu intervenieren (also eine Klarstellung zu liefern), die inhaltlich aus dem Ruder laufen. Ich denke, dieser Thread wäre eine gute Gelegenheit, um diese Vorgehensweise mal auszuprobieren. :badgrin:
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
 
Beiträge: 6728
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin

Re: Object destroyen

Beitragvon Manfred » Mi, 14. Nov 2012 13:56

habe ich indirekt schon angeleiert....
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
 
Beiträge: 16547
Registriert: Di, 29. Nov 2005 17:58
Wohnort: Kreis Wesel

Nächste

Zurück zu OOP

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron