I notice that the Session Count of my Web app stays nice and low for a couple days, with it clearly dropping as user sessions die out. Then, after a couple days, the Session Count rises and rises, even when user sessions have supposedly timed out. Reading posts on this forum makes me think this is a memory leak, most likely caused by a circular reference.
I imagine the most likely culprit is a Session property called MailSocket1, which points to an SMTPSecureSocket created in Session.Open. Can I simply place this in Session.Close to handle this? …
[quote=272685:@Ralph Alvy]I notice that the Session Count of my Web app stays nice and low for a couple days, with it clearly dropping as user sessions die out. Then, after a couple days, the Session Count rises and rises, even when user sessions have supposedly timed out. Reading posts on this forum makes me think this is a memory leak, most likely caused by a circular reference.
I imagine the most likely culprit is a Session property called MailSocket1, which points to an SMTPSecureSocket created in Session.Open. Can I simply place this in Session.Close to handle this? …
Self.MailSocket1 = Nil
No. Session.Close fires too late for that. I’d suggest setting that to Nil when you’re truly done with it.
That said, unless your MailSocket has a property that points to the Session, this probably isn’t the cause of your troubles.
Since the above MailSocket property references Session, albeit weakly, I’m now creating the socket only as needed, and setting it to Nil when not needed. I’ll see how that works.
I found I was using 2 WebPage properties to store Session.DB.LastRowID to make it “easier to code.” I replaced all usages of those properties with Session.DB.LastRowID and will see if that makes a difference.
Hmmm … the more I think about this, the above doesn’t seem like what Greg is talking about. The WebPage properties I found are not computed properties. They are updated my methods as needed.
[quote=272733:@Ralph Alvy]I’ll add this to Session.Close and see if that helps:
If DB.Connect Then DB.Close
Though I don’t see any circular referring going on here, so I expect you’re going to say it also is not my culprit.[/quote]
Don’t do this. You’re connecting to the database just to close it.
a) Xojo will close the db for you
b) I would assume that session.close never happens on the sessions that don’t go away, so any code in session.close isn’t related to, nor will it fix, the problem.
Thanks, Tim. In terms of Session.Close, I was assuming that, after a couple days of the Web App running fine, when users start seeing the Disconnect Message (after timing out) while the Session Count doesn’t decrease, even after many hours, Session.Close was firing but somehow Xojo was just not releasing the session. That is, I assumed that, perhaps incorrectly, if that Disconnect Message appears, Session.Close ran.
So I thought maybe the DB connection wasn’t closing in these situations and was keeping the session from closing, because I didn’t explicitly close it in Session.Close. In time mean time, I looking for any possible way I have circular references to Session, since this DB connection concern is sounding like a fool’s errand.
Going back to circular references, try doing a search for “as Session” in your project. If you have any of those as properties in any WebControl or WebView subclass, that would be the place to start. That said, Sessions are not the only things that cause leaks like this. Sessions keep an array of WebPages, Pages, Dialogs and Containers keep an array of WebControls and other WebViews. Any of the subcontrols that keep references to another object at the same level or above it within that same session could cause a leak.
When looking for objects that “keep references” to other objects, are such 'kept references" confined to computed properties? If so, I have none anywhere in the project except for a the WeakRef noted earlier in this post (the property MailSocket). Also, I have no methods that use the Assigns keyword, should that be relevant.
So when a WebPage1 method sets WebPage1.MyProperty to Session.MyProperty, this is considered a “kept reference” and could cause a memory leak? I wouldn’t have thought that, since they are not logically linked like they would be if WebPage1.MyProperty was a computed property.
I have no idea why you would think that computed makes any difference
Any variable, property (computed or not as they are both properties), that is assigned an OBJECT reference (ie/ its not a string, integer, double etc) and its not a weak reference holds a hard reference. And if there happens to be a cycle of hard references this can cause a leak
Class A
property refToSomeBInstance as ClassB
end class
Class B
property refToSomeAInstance as ClassA
end class
dim Ainstance as new ClassA
dim Binstance as new ClassB
Ainstance.refToSomeBInstance = Binstance
Binstance.refToSomeAInstance = Ainstance
a = nil
b = nil
Since Ainstance refers to Binstance and Binstance refers to Ainstance when I set my local variables to nil the ONLY thing that will happen is that I cannot reference them any more. They wont be removed from memory.
Thats a leak
Ainstance has a reference to Binstance so keeps Binstance alive (its reference count ?0)
And Binstance has a reference to Ainstance so keeps Ainstance alive (its reference count ? 0)