CLASS and Delete object xxxxx

Posted by goo on 19-Dec-2016 12:31

OE116

I wounder how the cleanup is done, or if it is done when doing the following code:

If the class has a def temp-table ... etc.

def var oClass as class myClass().

do i = 1 to 100:

  oClass = new myClass().

  :

 : 

end.

 delete object oClass.

Will the delete fix all of them, or do I have to handle this different? and if so, how?

//Geir Otto

Posted by Mike Fechner on 19-Dec-2016 13:28

Documentation … and reality ;-) the ABL GC works synchronously. Reference gone. Object gone.
 
Von: Tim Kuehn [mailto:bounce-timk519@community.progress.com]
Gesendet: Montag, 19. Dezember 2016 20:21
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] CLASS and Delete object xxxxx
 
Update from Progress Community
 
Mike Fechner
So in short – all your objects will be killed in the order the way instantiated.

The docs specifically state there is no guarantee they'll be deleted in any particular order - if your code depends on order of deletion the application has to do it explicitly.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

All Replies

Posted by Mike Fechner on 19-Dec-2016 13:08

Assuming there are no other references hanging around to your myClass instances…
 
The DELETE OBJECT oClass will only delete the last instance.
 
But don’t panic. The instance 1 to 99 will be cleaned up by the next iteration of the DO i = 1 TO 100 loop. Everytime you assign a NEW myClass to oClass, the last reference to the previous myClass instance is voided and the ABL garbage collector will trash the orphaned instance.
 
So in short – all your objects will be killed in the order the way instantiated.
Von: goo [mailto:bounce-goo@community.progress.com]
Gesendet: Montag, 19. Dezember 2016 19:33
An: TU.OE.Development@community.progress.com
Betreff: [Technical Users - OE Development] CLASS and Delete object xxxxx
 
Update from Progress Community
 

OE116

I wounder how the cleanup is done, or if it is done when doing the following code:

If the class has a def temp-table ... etc.

def var oClass as class myClass().

do i = 1 to 100:

  oClass = new myClass().

  :

 : 

end.

 delete object oClass.

Will the delete fix all of them, or do I have to handle this different? and if so, how?

//Geir Otto

View online

 

You received this notification because you subscribed to the forum.  To stop receiving updates from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Brian K. Maher on 19-Dec-2016 13:10

Geir,
 
Use -clientlog <filename> -logginglevel 4 -logentrytypes DynObjects.Class to see what happens.
 
Brian

Posted by David Abdala on 19-Dec-2016 13:11

Garbage collection will "probably fix it", but..

I prefer to DELETE whatever I CREATE, so:

do i=1 to 100 ON ERROR UNDO, THROW:

oClass = new myClass().

.

.

FINALLY:

 DELETE OBJECT oClass.

END.

end.

My recommendation:

- Delete everything you create

- Delete nothing

anything in between is confusing.

David.

Posted by Mike Fechner on 19-Dec-2016 13:18

So puristic J
 
Just kidding. I share your PoV. But I also believe it’s absolutely essential for every OOABL developer to understand how/when the GC works.
 
Von: David Abdala [mailto:bounce-dabdala@community.progress.com]
Gesendet: Montag, 19. Dezember 2016 20:12
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] CLASS and Delete object xxxxx
 
Update from Progress Community
 

Garbage collection will "probably fix it", but..

I prefer to DELETE whatever I CREATE, so:

do i=1 to 100 ON ERROR UNDO, THROW:

oClass = new myClass().

.

.

FINALLY:

 DELETE OBJECT oClass.

END.

end.

My recommendation:

- Delete everything you create

- Delete nothing

anything in between is confusing.

David.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Tim Kuehn on 19-Dec-2016 13:19

[quote user="Mike Fechner"]

So in short – all your objects will be killed in the order the way instantiated.

[/quote]

The docs specifically state there is no guarantee they'll be deleted in any particular order - if your code depends on order of deletion the application has to do it explicitly.

Posted by Mike Fechner on 19-Dec-2016 13:28

Documentation … and reality ;-) the ABL GC works synchronously. Reference gone. Object gone.
Von: Tim Kuehn [mailto:bounce-timk519@community.progress.com]
Gesendet: Montag, 19. Dezember 2016 20:21
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] CLASS and Delete object xxxxx
 
Update from Progress Community
 
Mike Fechner
So in short – all your objects will be killed in the order the way instantiated.

The docs specifically state there is no guarantee they'll be deleted in any particular order - if your code depends on order of deletion the application has to do it explicitly.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Tim Kuehn on 19-Dec-2016 13:41

Documentation … and reality ;-) the ABL GC works synchronously. Reference gone. Object gone.

Right now that's true, and will be true until PSC decides to change the GC algorithm to something else. There are already requests in the works for changes like deferring all object deletions until the end of an appserver call for performance reasons. 

Posted by goo on 19-Dec-2016 14:15

Thanks, all, I hoped that was the way it worked.

Posted by Lieven De Foor on 22-Dec-2016 04:30

I would recommend against explicitly deleting objects using the delete object statement.

In your case each iteration of the loop will cause the reference to the previous object to be overwritten with the new one, causing it to get garbage collected (when the actual collection occurs should not concern you).

Only the last iteration's object will stay around for as long as there's a reference to it. If the variable that references it goes out of scope, that object will also be release and eventually garbage collected.

For global variables (or similar) just set them to ? to clear the reference and let the garbage collector do its work.

Posted by David Abdala on 22-Dec-2016 05:04

That is like recommending to leave your house door wide open, for the garbage collector guy to pick up the garbage for you. It may sound like a "comfortable" idea, but I will never suggest that.

It's truly very optimistic. You will never really know how many references there are to an object, unless you fully control the class implementation, which is never true for most systems.

References to an object are not only the variables where you initially store the object, but also any reference another object may have to it. Can you be sure about what happens to an object that PUBLISH and it's explicit reference is lost? I don't, I won't bet on it, it may change at any moment, as none of us controls garbage collector implementation.

Posted by goo on 22-Dec-2016 05:11

So what do you recommend to do a controlled garbage collection?

Posted by David Abdala on 22-Dec-2016 05:51

I always recommend to explicitly delete objects that you don't longer need. That not only ensures there are no "hanging around objects" but also helps others understand the code.

Think about another programmer looking at the code:

- The object is not deleted because is garbage collected

- The object is not deleted because is used somewhere else

- The object is not deleted because is internally referenced by global objects

You should document that, it's a lot easier to just delete the object. Explicitly deleting objects has no drawbacks, not doing so does.

Garbage collection is a great feature but should not be used as a "programming practice" because it may bite you harder than you can imagine, and if that happens the only solution will be to go back to the code and add all the "missing deletes".

In your original example, adding a FINALLY block where you DELETE the object, is more than enough, and puts your intentions very clearly. My first thinking of  your example was that you created 100 objects to do a "parallel" sort of stuff with all of them, only because there was no DELETE statement.. (yes, I know I'm weird..)

Posted by marian.edu on 22-Dec-2016 06:36

I’m definitively with David on this… and I do hate the ‘dispose (anti) pattern’ as well, mind you even in 4GL there are ‘unmanaged resources’ that you need to clean yourself as won’t be handled by the GC (sockets, com handles, sax/x-document, etc).


On the other hand the delete object statement can be used to kill one’s references if you get hold of them… like a public get only property, maybe it would be an idea to have delete object throw an error if exercised on a private set property but that shows how little fait one can have in his/her fellow developers ;)


Marian Edu

Acorn IT 
+40 740 036 212

Posted by goo on 22-Dec-2016 06:50

In 4GL we would do something like this:
Is it possible or necessary to do something like that when it comes to use of oObject = NEW ……. ?? Or will each object that has been lost ref. oObject = NEW will override previous ref to the object, be deleted because lack of reference ?
 
***********************  you see the picture J
Def temp-table ttCollect no-undo
  Field hObject as handle
  .
 
:
I.ex if I make a call to a external procedure
 
:
Run blabla.p set hTmp.
 
AddCollect(hTmp).
:
:
 
 
FINNALY:
  For each ttCollect:
    Delete object ttCollect.hObject no-error.
  End.
END.
*************************
Fra: marian.edu [mailto:bounce-marianedu@community.progress.com]
Sendt: torsdag 22. desember 2016 13.38
Til: TU.OE.Development@community.progress.com
Emne: RE: [Technical Users - OE Development] CLASS and Delete object xxxxx
 
Update from Progress Community
 

I’m definitively with David on this… and I do hate the ‘dispose (anti) pattern’ as well, mind you even in 4GL there are ‘unmanaged resources’ that you need to clean yourself as won’t be handled by the GC (sockets, com handles, sax/x-document, etc).

 
On the other hand the delete object statement can be used to kill one’s references if you get hold of them… like a public get only property, maybe it would be an idea to have delete object throw an error if exercised on a private set property but that shows how little fait one can have in his/her fellow developers ;)
 
 
Marian Edu
 
Acorn IT 
+40 740 036 212
 

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by Tim Kuehn on 22-Dec-2016 07:48

I recently had this bite me in production - a Progress-supplied class had something going on under the covers that prevented it from getting GC'd, and it didn't get caught until it got to production.

DELETE OBJECT never harms and can save you from production related excitement.

Posted by Peter Judge on 22-Dec-2016 07:48

You can add a field to ttCollect that holds object references (FIELD oObject AS Progress.Lang.Object) . You don’t even need to turn off GC since you’re now holding a reference :) You can turn off GC via the -noGC switch.
 
FOR EACH ttCollect:
   DELETE OBJECT hObject NO-ERROR.
  // new line
   DELETE OBJECT oObject NO-ERROR.
END.
 
 
If you’re using 11.6.3 (I think) the OpenEdge.Core.WidgetHandle object can delete the handle it wraps automatically
objHandle = NEW OpenEdge.Core.WidgetHandle(hdlProcedure, true).
MESSAGE "Destroy=" objHandle:AutoDestroy.   // Destroy=TRUE
 
 
 

Posted by Rick Terrell on 22-Dec-2016 08:36

Normally, I would agree with both David and Marian.  However, the Progress OO manual states:

"Progress Software Corporation recommends that you allow garbage collection to delete

class-based objects whose reference counts are 0."

Take that as you will...

Posted by marian.edu on 22-Dec-2016 08:42

And who’s stoping the GC to ‘delete class-based object whose references counts are 0’? I certainly don’t do anything of that kind, you’re just trying to put me on the naughty list?  :)


Marian Edu

Acorn IT 
+40 740 036 212

Posted by Tim Kuehn on 22-Dec-2016 08:56

Ask Julian how he learned about the bidirection linkages that result from using publish/subscribe eventually leading to an out-of-memory condition...

Posted by Peter Judge on 22-Dec-2016 09:02

They’re not really bi-directional. It’s just that the direction isn‘t the one you’d expect :)

Posted by Laura Stern on 22-Dec-2016 09:05

Coming from the Progress Software Corporation side, I would say that the recommendation to use garbage collection is a simplification.  There are advantages/disadvantages on both sides:

* There is nothing wrong with doing DELETE OBJECT if you are sure that the object is not being used anywhere.  If it is not a straight-forward scenario and thus you are not sure, it's better to let garbage collection take care of it.

* The AVM does not garbage delete an object when it is part of a circular reference. For those cases, you may want to use DELETE OBJECT (the other way is to break the circle by clearing one or more references). This usually comes up with Forms and and classes that use event subscriptions.  Though again, when you do it, you have to be sure that you are not deleting something that is being used.  

In the example that started all this, with doing NEW in a loop and assigning the new class reference into the same variable each time, there is no ambiguity.  Garbage collection will handle this just fine and there is no need whatsoever for DELETE OBJECT.   And for the same reason, there is no problem if you do use DELETE OBJECT.  So take your pick.

Posted by Peter Judge on 22-Dec-2016 09:16

There is also the case where you cannot really manually clean up:  if you pass NEW MyObject() as an argument into a method without the use of an intermediary variable. With the snippet below you must let GC do the cleanup, unless you want to have to use a variable all the time.
 
 
obj:SomeMethod(NEW App.Arg(“val”, value2, …) ).
 
 
method public void SomeMethod (input objRef as Progress.Lang.Object):
end method
 
 

This thread is closed