Memory leak when using iFrames with javaScript

2019-03-31 06:51发布

I have a strange behaviour in (at least) IE11 and Edge (minimaly in Chrome). I create an iFrame and detach it afterwards but memory keeps increasing. In this iFrame only an empty page with javaScript imports is loaded.

I found some suggestions to change src of iFrame to about:blank but it still isn't working. Has anyone an idea what is going wrong?

Edit:

I tried it with the jQuery purgeFrame plugin and changed speed and iteration count.

Since it seems to be mainly a IE11 and Edge problem we also posted it on https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8449104/

The new code for the outer frame is:

<!doctype html>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <script type="text/javascript">
        var counter =0;

        /*
        * jQuery purgeFrame
        * A jQuery plugin to clean up Iframes and make IE happy
        *
        * Copyright (c) March 2014 Tom Mooney
        * licensed under the MIT license, http://www.opensource.org/licenses/mit-license.php
        */

        (function ($) {
            $.fn.purgeFrame = function () {
                var deferred = purge(this);

                return deferred;
            };

            function purge($frame) {
                var len = $frame.length
                var deferred = $.Deferred();
                $frame.one('load', function () {
                    try
                    {
                        $(this.contentWindow).empty();

                        len -= 1;
                        if (len <= 0) {
                            $(this).remove();
                        }

                        $frame = null;
                    }
                    finally {
                        deferred.resolve();
                    }
                });

                //Set src to about:blank to so that contentWindow can be manipulated on cross-domain iframes
                $frame.attr('src', 'about:blank');

                if ($frame.length === 0) {
                    deferred.resolve();
                }

                return deferred.promise();
            }
        }(jQuery));

        $(document).ready(function () {
            var myTimer = setInterval(
                    function(){ 
                        var contentContainer = $("#contentDiv");
                        var iFrame = $('<iframe class="contentFrame" frameborder="0" name="bla" style="overflow:auto; width: 100%; height: 100%;" src="leere.html"></iframe>');
                        contentContainer.append(iFrame);
                        $(iFrame).purgeFrame().done(function() {
                            console.log("deleted frame");
                            iFrame = null;
                        });
                        if (counter == 1000) {
                            clearInterval(myTimer);
                        }
                        counter++;
                    }, 50
                );

        });
    </script>
</head>
<body>
    <div id="contentDiv" style="width:100%; height:100%"></div>
</body>
</html>

The loaded html (leere.html)

<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</head>
<body>
Test
</body>
</html>

Memory Usage in IE11 (3x 1000 cycles) Picture of Memory Usage in IE11 Memory Usage in Edge (1x 1000 cycles) enter image description here

1条回答
叼着烟拽天下
2楼-- · 2019-03-31 07:42

I ran the webpage and used Chrome's Task Manager to monitor the memory consumption of the tab. I changed the number of intervals to 150, memory went to 84MB, stayed there for a while and then dropped back to 20MB. Memory consumption also drops after a while in IE.

My guess is that when you remove the iFrame and set the variable to null memory is not released right away but only during garbage collection after a while. As far as I know there is no way for you to forcibly instruct the browser to do garbage collection from JS. So there's nothing you can do about it other than rewrite your code to not create too many new DOM objects constantly.

查看更多
登录 后发表回答