Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Wed Dec 11, 2019 4:43 pm
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 3:25 pm 
Offline
User avatar

Joined: Thu Sep 10, 2009 2:50 am
Posts: 418
Location: Santa Cruz, CA, USA
Using AddHandler adds to the reference count. So a Socket with reference to a Timer property which has a reference to a Socket method for event callback creates a cyclic link. Losing reference to such a Socket will not be garbage collected, you'd need to RemoveHandler, nil the Timer property or use WeakAddressOf when AddHandlering.

I have no idea if that's part of your problem. StackOverflows make me think of accidental recursion.


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 4:53 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
@lukus001: Strange; I really (really, really) ensured that the network socket object is created just once. And after making above mentioned modification (first disabling timer, then doing something time-consuming), the behaviour disappeared. I'm using latest RS on OS X 10.8.3.

Anyway, I consider this as something only the computer could explain... . ;-)

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 4:56 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
@doofus: The timer is already part of the object, it's not an external one.

But I guess you (and lukus001) are right... it must have something to do with recursion, since we already figured out that it's technically impossible that the timer object fires simultaneously.

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 6:06 pm 
Offline
User avatar

Joined: Thu Sep 10, 2009 2:50 am
Posts: 418
Location: Santa Cruz, CA, USA
tobiaseichner wrote:
@doofus: The timer is already part of the object, it's not an external one.

That's what I mean. The object references the timer and the timer references the object creating a cyclic link.
If you try to dispose of such an object by setting it nil to be garbage collected it will still persist in memory even though your app has no way to access it. And running timers will continue to run in that memory leaked state.

Here's some code to demonstrate. Reference to the instance created in pushbutton.Action is lost at the end of the method but the instance lives on and the timer continues to fire. (hmmm, maybe it's still accessible through the Runtime module.)

Class Class1
MyTimer As Timer
Sub Constructor()
MyTimer = new Timer
AddHandler MyTimer.Action, AddressOf MyAction
MyTimer.Period = 2000
MyTimer.Mode = 2
End Sub
Sub MyAction(sender As Timer)
msgbox "MyAction fired"
End Sub
End Class1

Sub Event Pushbutton1.Action
dim c As new Class1 //create instance
End //lose reference to instance
//...still in memory and running


Yup, the instance is accessible through the Runtime module. So not technically a memory leak but very difficult to manage.


Last edited by doofus on Sat May 25, 2013 6:20 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 6:19 pm 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
I see... thanks for your sample code to explain it. :-)

Guess it's sufficient to disable the timer in order to break this ?

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 6:24 pm 
Offline

Joined: Sat Jul 16, 2011 2:45 pm
Posts: 76
tobiaseichner wrote:
I see... thanks for your sample code to explain it. :-)

Guess it's sufficient to disable the timer in order to break this ?

Tobias.
Just use removehandler or weakaddressof instead of addressof (just have a quick look at the documentation on them)

Edit: to clarify.

Disabling the Timer just means the event wont fire (.enabled = false) - you'll still have a reference to an object instance (due to circular referencing) which will lead to those objects not being cleaned out from memory (assuming they are to be disposed of)

As far as I know, you can't directly "delete" an object in Real Studio - you can only remove all references to that object and Real Studio will come along at some point and actually do the memory clean up for you. Changing a property containing an object instance to nil would remove a reference but in this case it wouldn't necessarily mean you removed the last reference - Addhandler (I assume) is part of the internal framework in regards to dispatching events, which means internally it will keep 1 reference when using AddressOf.

RemoveHandler or WeakAddressOf will facilitate the normal reference count based cleanup and avoid circular referencing i.e. no internal reference counts kept.

Of course, if you simply want to create a socket, do some timer based actions, close it and repeat the same process on a second connection; you probably don't need to create entirely new object instance every time - you can disable the timer and close the connection and simply change the connection details, connect and then enable the timer again (assuming you dont have any other related properties that would contain unwanted residual data from the previous task)


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 7:38 pm 
Offline
User avatar

Joined: Mon Apr 02, 2007 2:08 am
Posts: 1225
Location: San Francisco, CA, USA
tobiaseichner wrote:
>
Yes, the sockets are closed, either by the function we talked about or somewhere else in code.

Sockets are special. The TCPSocket class keeps a reference to itself, and so will not destruct, until it disconnects. If you're counting on a socket to be destroyed when losing scope then you must make sure it's disconnected or it will stick around until the other side disconnects.
Quote:
But even we consider the socket being not closed, why are there dozens of socket objects left open, even just a single one has been created before ?

Are you using the ServerSocket class? The ServerSocket will create new sockets as needed to meet its minimum sockets available setting.

_________________
Boredom Software


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 7:59 pm 
Offline

Joined: Fri Jan 06, 2006 3:21 pm
Posts: 12388
Location: Portland, OR USA
lukus001 wrote:
As far as I know, you can't directly "delete" an object in Real Studio - you can only remove all references to that object and Real Studio will come along at some point and actually do the memory clean up for you.

A point of clarification: Objects are destroyed immediately. There is no process running in the background that cleans up unused objects. The moment the reference count reaches zero, the object will be destructed. This can be significant if you have a lengthy destructor or if the destructor has any side effects. The destructor code runs inline with the code that reduces the reference count to zero. Eg.,

dim A as new B
A.DoSomething
A = nil
A = new B

The destructor for A runs immediately upon setting it to nil:

dim A as new B
A.DoSomething
A = nil
<<< Destructor code runs here
A = new B


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sat May 25, 2013 8:08 pm 
Offline
User avatar

Joined: Sun Aug 05, 2007 10:46 am
Posts: 4931
Location: San Diego, CA
Well at least some of the recent posts seem to provide some vindication for my original statement

_________________
Dave Sisemore
iMac I7[2012], OSX Mountain Lion 10.8.3 RB2012r2.1
Note : I am not interested in any solutions that involve custom Plug-ins of any kind


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sun May 26, 2013 8:20 am 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
@charonn0: No ServerSocket class is used; just TCPSockets (and its derivates like SMTPSocket).

Since the timer is part of the TCPSocket object, it seems not to influence reference counting even when using "addressof". So after disconnecting the TCPSocket object, it is gone (just checked with the debugger).

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sun May 26, 2013 9:38 am 
Offline
User avatar

Joined: Thu Sep 10, 2009 2:50 am
Posts: 418
Location: Santa Cruz, CA, USA
tobiaseichner wrote:
Since the timer is part of the TCPSocket object, it seems not to influence reference counting even when using "addressof". So after disconnecting the TCPSocket object, it is gone (just checked with the debugger).


In the debugger these 'leaked' objects won't show up in the usual place. Navigate to Globals > Runtime > Contents for a full list of active instances, probably a very long list, where you can see how many of your classes are around.

Or add this to a pushbutton somewheres and check the counts of your class at various times.
dim count As integer
for i As integer = 0 to Runtime.ObjectCount - 1
if Runtime.ObjectClass(i) = "Class1" then count = count + 1
next
MsgBox "found Class1's: " + Str(count)


Top
 Profile  
Reply with quote  
 Post subject: Re: Does a Timer always fire once ?
PostPosted: Sun May 26, 2013 10:38 am 
Offline
User avatar

Joined: Sat Jan 29, 2011 6:24 pm
Posts: 33
Location: Germany, Europe
@doofus: Thanks for your help. :-) Yes, there were tons of leftover objects... after changing AddressOf to WeakAddressOf, anything looks much better.

Anyway, I have a Windows version of the software running now for about three weeks on a virtual machine. The software is configured to perform a job that requires opening a HTTPSocket every five minutes. Until yet, no problems occurred and memory usage is at an acceptable level.

I wonder if you have a guess why. If I understood the discussion correctly, such objects are never removed (because even if the network socket disconnects, we still have the reference to the timer object that should keep the object alive). Unfortunately, I have no direct access to this Windows machine, otherwise I would deeper looking into this by myself.

Tobias.

_________________
STAR ENTERPRISE - The Universe of powerful Internet and Business Services
Consulting | Software development | Services
Internet: www.starenterprise.com - info@starenterprise.com


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page Previous  1, 2

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group