代码之家  ›  专栏  ›  技术社区  ›  Dustin

Javascript+IMG标记=内存泄漏。有更好的方法吗?

  •  8
  • Dustin  · 技术社区  · 17 年前

    if(number_of_things_seen > 10) {
      $('#shots li:last-child').remove();
    }
    
    $('<li><img src="' + p.ProductImageSmall + '"></li>').prependTo('#shots');
    

    然而,它似乎泄漏了相当多的内存。从视觉上看,它做了正确的事情,但足迹无限期地增长。

    Safari的DOM检查器显示DOM是我期望的样子,但它似乎维护了对它显示的每个图像的引用(如中所示) this screenshot

    $('#shots li:last-child img').remove();
    

    对删除声明没有明显影响。

    是否有一些必要的魔法让浏览器发布这些东西?

    8 回复  |  直到 17 年前
        1
  •  2
  •   Rob Colburn    17 年前

    浏览器因内存泄漏而臭名昭著。当页面长时间运行时,似乎会出现问题。在内存不足之前刷新页面如何?

    window.setTimeout("location.reload()",1000*60*60);//refresh in an hour
    
        2
  •  1
  •   redsquare    17 年前

    你能试着改变最后一个孩子的src,看看这是否有区别吗? 然后可以将该元素移动为第一个子元素

    //not tested
    
    var $list=$('#shots>li');
    $list.filter(':last-child').children('img')
    .attr('src', p.ProductImageSmall)
    .parent()
    .insertBefore( $list.eq(0) );
    
        3
  •  1
  •   Tomalak    17 年前

    Mozilla Developer Center on removeChild() :

    这是关键-重用删除的子项,而不是重复创建新的子项。

    // I'm sure there is a nicer way to do it in jQuery
    if(number_of_things_seen > 10) {
      var shots = document.getElementById("shots");
      var li    = shots.getElementsByTagName("LI");
      var move  = shots.removeChild(li[li.length-1]);
      move.getElementsByTagName("IMG")[0].src = p.ProductImageSmall;
      shots.insertBefore(move, li[0]);
    }
    
        4
  •  1
  •   Georg Schölly Crazy Developer    17 年前

    我怀疑Safari会缓存所有的图像,只要你呆在同一个网站上,你对此无能为力。如果幸运的话,Safari会在达到某个限制后释放不需要的对象。

        5
  •  0
  •   Scott Evernden    17 年前

    你观察这种“无限增长”有多久了?垃圾收集器的一些实现不一定能如此快速地将内存返回操作系统。您能否将您正在尝试做的事情提取到一个真正简单的测试中(例如,反复设置图像的src),而不使用ajax或回调?你能用其他浏览器试试这个吗?

        6
  •  0
  •   redsquare    17 年前
        7
  •  0
  •   redsquare    17 年前

    代码中的insertBefore语句似乎引起了一些问题。如果您看到这个更进一步的测试用例,那么即使我清空了最后一个子项并插入了一个新的dom片段,内存使用仍然保持相当稳定。性能优于上次尝试。

    http://pastebin.me/4936519fea2cf

        8
  •  0
  •   Willem M.    12 年前

    正如我最近发现的,Firefox中有一个bug导致孤立的IMG标签泄漏。

    if(number_of_things_seen > 10) {
      $('#shots li:last-child').remove();
    }
    
    $('<li><div style="background-image: url(\'' + p.ProductImageSmall +
         '\'); background-repeat: no-repeat; background-position: center; '+
         ' width: 20px; height: 20px"></div></li>').prependTo('#shots');
    

    检查这是否解决了内存泄漏问题。