jQuery.data 的优势之一与原始 expando 属性(您可以分配给 DOM 节点的任意属性)相比,jQuery.data “不受循环引用的影响,因此不会发生内存泄漏”。来自 Google 的一篇标题为 "Optimizing JavaScript code" 的文章进入更多细节:
The most common memory leaks for web applications involve circular references between the JavaScript script engine and the browsers' C++ objects' implementing the DOM (e.g. between the JavaScript script engine and Internet Explorer's COM infrastructure, or between the JavaScript engine and Firefox XPCOM infrastructure).
它列出了循环引用模式的两个示例:
DOM 元素 → 事件处理程序 → 闭包作用域 → DOM
DOM 元素 → 通过 expando → 中间对象 → DOM 元素
但是,如果 DOM 节点和 JavaScript 对象之间的引用循环产生内存泄漏,这是否意味着任何重要的事件处理程序(例如 onclick)都会产生这种泄漏?我不明白事件处理程序怎么可能避免引用循环,因为我的看法是:
DOM 元素引用事件处理程序。
事件处理程序引用 DOM(直接或间接)。在任何情况下,几乎不可能避免在任何有趣的事件处理程序中引用 window,除非编写一个 setInterval 循环来从全局队列中读取操作。
有人可以提供 JavaScript ↔ DOM 循环引用问题的准确解释吗?我想澄清的事情:
哪些浏览器会受到影响? jQuery 源代码中的评论特别提到了 IE6-7,但 Google 文章表明 Firefox 也受到了影响。
expando 属性和事件处理程序在内存泄漏方面是否有所不同?还是这两个代码片段都容易受到同一种内存泄漏的影响?
// Create an expando that references to its own element.
var elem = document.getElementById('foo');
elem.myself = elem;
// Create an event handler that references its own element.
var elem = document.getElementById('foo');
elem.onclick = function() {
elem.style.display = 'none';
};
如果页面由于循环引用而泄漏内存,泄漏会持续到整个浏览器应用程序关闭,还是在窗口/选项卡关闭时释放内存?
最佳答案
复制这些链接中的所有内容可能不值得,所以我建议您阅读并查看 other Google search hits :
javascript, circular references and memory leaks
Do you know what may cause memory leaks in JavaScript?
http://www.ibm.com/developerworks/web/library/wa-memleak/
http://www.ibm.com/developerworks/web/library/wa-sieve/index.html?ca=drs-
http://code.google.com/p/google-web-toolkit/wiki/UnderstandingMemoryLeaks
最严重的内存泄漏出现在 IE6 中,其中泄漏是永久性的(即使在您离开受影响的网页之后)。其他泄漏通常仅在您位于该特定页面上时才会发生,并在您离开该页面时得到清理。
事实是浏览器应该能够处理循环引用。它应该能够看到,即使 DOM 元素仍被 JavaScript 元素引用,JavaScript 元素本身仅存在,因为 DOM 元素仍然存在,因此没有真正的外部引用留给 DOM 元素.旧版本的 IE 不擅长的正是这种认识。因此,在涉及事件处理程序的代码引用中,垃圾收集器需要足够聪明,知道在 JavaScript 中唯一留给 DOM 元素的引用是当 DOM 元素及其事件处理程序被删除时它们本身会消失的引用——因此没有真正的外部引用,因此删除 DOM 元素和事件处理程序是安全的。这是所有垃圾收集器都必须处理的一般循环引用问题的更复杂版本,其中对象 A 引用对象 B,对象 B 引用对象 A,但没有其他对象引用 A 或 B,因此两者都可以被释放.
jQuery 的 .data() 使事情变得更可靠,因为旧版本的 IE 对添加到 DOM 元素的属性有一个特殊的问题,并且没有正确处理涉及这些数据的循环引用属性,因此不会在它应该有的时候释放东西(泄漏)。 .data() 通过仅在 DOM 元素上使用一个添加的属性来解决这个问题,该属性是一个安全、无泄漏的字符串。该字符串随后成为 JavaScript 对象的键,该对象可以包含您希望与 DOM 元素关联的所有属性。因为这些属性都存储在纯 JavaScript 中,浏览器没有循环引用错误,所以这样做不会导致泄漏。
重要的是要意识到可能仍然存在一些循环引用,这没关系。解决方法是将循环引用移动到浏览器可以适当处理它们的地方,而不是将它们放在浏览器有错误的地方。
关于javascript - JavaScript <-> DOM 循环引用问题详解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10092619/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub