在使用带有JavaScript的iFrames时发生内存泄漏 [英] Memory leak when using iFrames with javaScript

查看:644
本文介绍了在使用带有JavaScript的iFrames时发生内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(至少)我有一个奇怪的行为IE11和Edge(在Chrome中最小)。之后我创建了一个iFrame并将其分开,但内存不断增加。在此iFrame中,只加载了一个带有javaScript导入的空白页面。



我发现了一些建议,将iFrame的src更改为about:blank,但它仍然无效。有没有人有一个想法是什么问题?

编辑:

我试着用jQuery purgeFrame插件,改变速度和迭代次数。

由于它似乎主要是IE11和Edge问题,我们也将它发布在
边缘内存使用情况(1x 1000周期)

解决方案

我运行了该网页并使用Chrome的任务管理器来监控该选项卡的内存消耗。我将间隔数改为150,内存达到84MB,在那里停留了一段时间,然后又回到了20MB。
在IE浏览器中一段时间​​后,内存消耗也会下降。



我的猜测是,当您删除iFrame并将变量设置为null时,内存不会立即释放但仅在一段时间后才进行垃圾回收。据我所知,你无法强制指示浏览器从JS进行垃圾回收。所以除了重写代码,不要不断创建太多新的DOM对象之外,你无能为力。


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) Memory Usage in Edge (1x 1000 cycles)

解决方案

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.

这篇关于在使用带有JavaScript的iFrames时发生内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆