Preventing memory leaks: best practice around accessing session properties

I came across a really helpful post (see link below) explaining how memory leaks can be caused due to circular references e.g. a WebContainer trying to access Session properties and therefore stops the session from being able to be destroyed when an end user closes the browser for instance.

WebPage: Instantiate or not? Best practice? - Targets / Web - Xojo Programming Forum

To me this implies that we should never reference Session properties from subclasses. If that’s the case, what’s best practice around accessing session properties from subclasses?

@Greg_O_Lone not sure if you can expand on the above post here?

Actually, it’s a little more complicated.

First of all, this is not about simply referring to Session or it’s properties, nor about subclasses of Session. It’s about objects that a Session itself has references of.

For instance a session has a hard-reference to every WebPage that is created for it, in an array, so you can iterate over them if necessary. Same holds true for the App itself, in that it holds a reference to each Session.

The problem described in those articles occurs if you were to add a property on a WebPage of type WebSession or Session and then somewhere in your code set it to Self.Session.

Now, because Xojo uses reference counting to decide when it’s okay for something to be destroyed when a user disconnects and has been away for 3 minutes, the framework says “oops, user is gone, time to close the session” and removes the reference it has to the session. At this point the session has a reference to the WebPage and the WebPage has one to the Session. Because of this, neither one will be destroyed. This is what we call a circular reference causing a memory leak.

The answer is often “don’t do that” but sometimes it’s not possible, so the answer is to work with WeakRefs. You could, for instance, use a WeakRef of the session in your webpage with a property and a computed property:

Private mMySession as WeakRef

Get MySession as Session
    If mMySession = Nil or mMySession.Value = Nil Then Return Nil

    Return Session(mMySession.Value)
End Get

And then when setting the property, use something like this:

mMySession = New WeakRef(Self.Session)

When referencing MySession you’ll need to always check if it’s Nil first.

Oh, and this has nothing to do with the simple data types like Strings and Integers, just Objects.

2 Likes

Thanks for the explanation - I now understand how the circular referencing is created!