How to not leak memory

2,978 views
Skip to first unread message

Domenic Denicola

unread,
Feb 24, 2012, 4:31:33 PM2/24/12
to knock...@googlegroups.com
I have the following helpers to work with non-Knockout areas of my code ("POJSOs"):

https://gist.github.com/1903866

However, if I use them, I leak memory and hold on to the subscriptions forever :(.

Is there any way I can hook into Knockouts internal cleaning-up abilities, so that when those run, I remove my subscriptions?

How do those work, anyway? I mean, if I remove an element from the DOM, do I need to clean it up to get rid of the Knockout stuff somehow? (This is not documented anywhere that I could find.)

Thanks,
-Domenic

rpn

unread,
Feb 24, 2012, 10:12:48 PM2/24/12
to knock...@googlegroups.com
A couple thoughts:
-When you create a subscription it returns a reference to the subscription.  With that reference you can call its .dispose() method to remove it.

-if you use a ko.computed instead of a subscription, then you can pass a function that is evaluated when it is evaluated to determine if it should be disposed like:
ko.computed({
    readfunction({
         return test(2;
    },
    disposeWhenfunction({
        return test(=== 0;
    }        
}); 

-if you use a ko.computed, you can pass a DOM node that will trigger disposal when it is removed by KO (using ko.cleanNode or ko.removeNode that calls ko.cleanNode, such as by the template binding).
ko.computed({
    readfunction({
         return test(2;
    },
    disposeWhenNodeIsRemoved: element    
});  

-You can also just call .dispose() on a ko.computed. 

-you can also add a callback to be executed when a DOM node is removed by KO like:

ko.utils.domNodeDisposal.addDisposeCallback(elementfunction({
    //your logic here
}); 

Hope that this gives you some ideas about how to hook into the clean up code.

Domenic Denicola

unread,
Feb 25, 2012, 12:32:13 AM2/25/12
to knock...@googlegroups.com

OK, this is pretty helpful, and should give me a solution for my two utility functions.

 

But, from this I gather that whenever I remove elements from the DOM, I should be calling `ko.cleanNode` on them. (Or `ko.removeNode`?) Are these documented anywhere? I’m removing Knockout-bound elements all the time, but it sounds like they’re not getting cleaned up properly.

rpn

unread,
Feb 25, 2012, 12:38:04 AM2/25/12
to knock...@googlegroups.com
ko.cleanNode will recursively clean up the node and its children.  ko.removeNode will call ko.cleanNode and then try to remove the element from its parent.  If you are using the template/control-flow bindings, then this is done for you.

Domenic Denicola

unread,
Feb 25, 2012, 12:39:07 AM2/25/12
to knock...@googlegroups.com

Right, but if I’m e.g. creating a dialog box, I should manually call `ko.removeNode` when closing the dialog box.

 

From: knock...@googlegroups.com [mailto:knock...@googlegroups.com] On Behalf Of rpn
Sent: Saturday, February 25, 2012 0:38
To: knock...@googlegroups.com
Subject: Re: How to not leak memory

 

ko.cleanNode will recursively clean up the node and its children.  ko.removeNode will call ko.cleanNode and then try to remove the element from its parent.  If you are using the template/control-flow bindings, then this is done for you.



On Friday, February 24, 2012 11:32:13 PM UTC-6, Domenic Denicola wrote:

OK, this is pretty helpful, and should give me a solution for my two utility functions.

 

But, from this I gather that whenever I remove elements from the DOM, I should be calling `ko.cleanNode` on them. (Or `ko.removeNode`?) Are these documented anywhere? I’m removing Knockout-bound elements all the time, but it sounds like they’re not getting cleaned up properly.

 

rpn

unread,
Feb 25, 2012, 12:42:46 AM2/25/12
to knock...@googlegroups.com
I'm not sure of your code structure, but if after closing your dialog, you normally remove the element from the DOM and it contained bindings, then you should call ko.removeNode.

Jeffer

unread,
May 28, 2012, 11:41:04 PM5/28/12
to knock...@googlegroups.com
I'm facing the same problem, some nodes are created dynamically/bound and removed and I'm worried that I'm not disposing of resources properly.  It would be great to have a clear description of the lifecycle of bound nodes with model views.  There is no mention about this on the ko website nor about ko.removeNode and when and why we should use it.  @Ryan: In your previous post you mention "If you are using the template/control-flow bindings, then this is done for you."  What do u mean by this?  Does this mean that whenever a bound element is removed from the dom, ko does the cleanup automatically?  Then in your last post u indicate that Domenic should use ko.removeNode...I'm confused!!

Thanks in advance for your clarifications

rpn

unread,
May 29, 2012, 8:44:31 AM5/29/12
to knock...@googlegroups.com
Hi Jeffer-
If you are using Knockout in the "normal" way, then KO will do some cleanup when adding/removing nodes.  The typical time that this happens is when re-rendering a template.  The control-flow bindings (if/with/foreach, etc.) are all wrappers to the template binding and would be included.  So, when Knockout removes previously rendered elements to render new elements, then it runs the ko.removeNode logic.  This mainly disposes of any computed observables created to track the bindings.   A custom binding can also register actions to happen during this disposal (like disposing of a 3rd party widget).  

In this thread, there was some discussion of dynamically adding/binding elements (not through normal KO templates).  In this case, it would be appropriate to call the clean up code. 

Hope that helps.

-Ryan

David Rosen

unread,
Jun 5, 2012, 3:27:17 PM6/5/12
to knock...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages