[Ur] Substantial memory leak in the JavaScript runtime

Saulo Araujo saulo2 at gmail.com
Wed Aug 24 15:02:04 EDT 2016


Hi Adam,

You are welcome! I am happy to say that your patch also fixes the memory
leak. I believe there is another memory leak in the JavaScript runtime (see
the end of the previous message). I am gonna look into it.

Sincerely,
Saulo

On Wed, Aug 24, 2016 at 1:17 PM, Adam Chlipala <adamc at csail.mit.edu> wrote:

> Thanks for spotting this problem.  I've pushed a different fix that makes
> dynamic input elements create <script> tags, so that the original dyn()
> code finds them to garbage-collect.  Does this change also seem to fix the
> problem?
>
> (I'd like to avoid using createNodeIterator(), which only became widely
> deployed about 5 years ago.  I think Ur/Web client-side reactive code today
> will still work on browsers from about the year 2000, and I'd like to keep
> it that way unless there's a very compelling reason to the contrary.)
>
> On 08/12/2016 09:55 PM, Saulo Araujo wrote:
>
> Hi,
>
> I believe there is a substantial memory leak in the JavaScript runtime of
> Ur/Web. To see it happening:
>
> 1) visit http://timesheet-ur.sauloaraujo.com:8080/TimeSheet/application
> with Google Chrome
> 2) open the developer tools by pressing f12
> 3) click in the "Profiles" tab
> 4) click in the "Take Heap Snapshot" radio button
> 5) click in the "Take Snapshot" button
> 6) type Detached in the "Class filter" text box (you will see that the
> heap has about 7MB and Detached DOM trees are retaining 0% of the memory -
> https://snag.gy/2nF9fz.jpg)
>
> 7) click 10 times in the foward icon (the one on the right of the "Date"
> header in the time sheet application)
> 9) click in the "Take Snapshot" button
> 10) type Detached in the "Class filter" text box (you will see that the
> heap has about 43MB and Detached DOM trees are retaining 16% of the memory
> - https://snag.gy/Crc3Vg.jpg)
>
> 11) click 10 times in the foward icon (the one on the right of the "Date"
> header in the time sheet application)
> 12) click in the "Take Snapshot" button
> 13) type Detached in the "Class filter" text box (you will see that the
> heap has about 78MB and Detached DOM trees are retaining 17% of the memory
> - https://snag.gy/P5BLhq.jpg)
>
> I have spent quite some time investigating this memory leak and I believe
> the problem is in the function recreate inside the function dyn:
>
> function dyn(pnode, s) {
>     if (suspendScripts)
>         return;
>
>     var x = document.createElement("script");
>     x.dead = false;
>     x.signal = s;
>     x.sources = null;
>     x.closures = null;
>
>     var firstChild = null;
>
>     x.recreate = function(v) {
>         for (var ls = x.closures; ls; ls = ls.next)
>             freeClosure(ls.data);
>
>         var next;
>         for (var child = firstChild; child && child != x; child = next) {
>             next = child.nextSibling;
>
>             killScript(child);
>             if (child.getElementsByTagName) {
>                 var arr = child.getElementsByTagName("script");
>                 for (var i = 0; i < arr.length; ++i)
>                     killScript(arr[i]);
>             }
> ...
>
> Note that recreate only kills <script> nodes . Therefore, <input>,
> <textarea> and <select> nodes created through <ctextbox>, <ctextarea> and
> <cselect> will continue to be in the dyns lists of its sources. To fix this
> memory leak, I propose changing the function dyn to
>
> function dyn(pnode, s) {
>     if (suspendScripts)
>         return;
>
>     var x = document.createElement("script");
>     x.dead = false;
>     x.signal = s;
>     x.sources = null;
>     x.closures = null;
>
>     var firstChild = null;
>
>     x.recreate = function(v) {
>         for (var ls = x.closures; ls; ls = ls.next)
>             freeClosure(ls.data);
>
>         var next;
>         for (var child = firstChild; child && child != x; child = next) {
>             next = child.nextSibling;
>
>             killDyns(child)
> ...
>
> Below is the function killDyns.
>
> function killDyns(node) {
>     var nodeIterator = document.createNodeIterator(node,
> NodeFilter.SHOW_ELEMENT, function (node) {
>         return node.dead !== undefined && node.dead === false
>     })
>     var node = nodeIterator.nextNode();
>     while (node) {
>         killScript(node);
>         node = nodeIterator.nextNode();
>     }
> }
>
> killDyns traverses all descendants of a node that have a dead attribute
> equal to false and kills them with killScript. Therefore, killDyns may be
> less performant than the code it substitutes, but I believe killDyns is
> less prone to memory leaks than the original code. There is another small
> change to be done in urweb.js. You can see all changes in
> https://github.com/saulo2/urweb/commit/dcd280c85595ceee60a4fb78a3bfaf
> 413a9eb7b8#diff-867e8dfbbc36419eefc0dfdf9db32883
>
> I did not make a pull request yet because I would like to know the opinion
> of the Ur/Web comitters about this fix. Maybe there is something that can
> be improved. Maybe there is a new bug in it :) In any case, repeating the
> previous steps with the proposed changes, I get the following results:
>
> 6) type Detached in the "Class filter" text box (you will see that the
> heap has about 7MB and Detached DOM trees are retaining 0% of the memory -
> https://snag.gy/NicJow.jpg)
> 10) type Detached in the "Class filter" text box (you will see that the
> heap has about 15MB and Detached DOM trees are retaining 0% of the memory -
> https://snag.gy/nuVfhg.jpg)
> 13) type Detached in the "Class filter" text box (you will see that the
> heap has about 21MB and Detached DOM trees are retaining 0% of the memory -
> https://snag.gy/aPeUuK.jpg)
>
> The new results suggest that there is another memory leak in the
> JavaScript Runtime. However, I have not looked into it yet.
>
> Sincerely,
> Saulo
>
>
> _______________________________________________
> Ur mailing listUr at impredicative.comhttp://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>
>
>
> _______________________________________________
> Ur mailing list
> Ur at impredicative.com
> http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.impredicative.com/pipermail/ur/attachments/20160824/748a2489/attachment-0001.html>


More information about the Ur mailing list