草庐IT

javascript - 这个 AJAX 模式是内存泄漏吗?

coder 2025-01-02 原文

考虑这个 Angular Js 中非常标准的方法示例,它更新 View :

$scope.fetchResults = function() {
    // Some local variable that will cause creation of closure
    var hugeData = serviceX.getMilionRecords();

    // Any call to any resource with success and error handlers.
    $http({
        method: "GET",
        url: "/rest-api/bulk-operation-x",
        params: { someParam: hugeData.length }

    }).success( function () {
        var length = hugeData.length;
        $scope.reportToUser("Success, that was " + length + " records being processed!";

    }).error( function () {
        var length = hugeData.length;
        $scope.reportToUser("Something went wrong while processing " + length + " records... :-(";
    });
};

这当然是假设性示例,但它很好地展示了模式,可以将其描述为在 AJAX 回调中重用局部变量。

当然,在两个处理程序(successerror)中,我们都在 hugeData 上创建了一个闭包,它直接从回调处理程序中引用。

我的问题是:由于 AJAX 调用的结果只能是成功或失败,重复使用这段代码是否会随着时间的推移导致内存泄漏?我会回答"is",但我无法在本地测试中可靠地证明这一点。

我想要一些更有经验的大师为我解释这个。我喜欢每天使用 Angular 的任何人的回复,但也欢迎任何 jquery 回复。

最佳答案

一旦将 $http() 调用的结果(或任何可以访问 hugeData 的对象或函数)返回到fetchResults 的外部范围。

使用您的代码,fetchResults 之外不会直接公开任何大的内容,$http() 调用的结果将一直存在,直到它成功或失败,然后调用相应的回调,最终得到 GC。

请参阅:http://jibbering.com/faq/notes/closures/#clIdRes

正如@ŁukaszBachman 所观察到的,这并不能保证没有内存泄漏。任何对大对象的悬垂引用或对范围内大对象的回调都会造成麻烦。

那么,让我们检查一下$q 实现($http 基于$q)。

如果你勾选https://github.com/angular/angular.js/blob/master/src/ng/q.js#L191 ,你可以看到 deferred 的 resolve() 方法首先将已注册的回调列表复制到该方法的本地变量中:

var callbacks = pending;

随后使外部 pending 无效(在 defer 级别定义)

pending = undefined;

然后,在下一次滴答时,执行回调。由于回调的参数本身可能是延迟的(进一步延迟执行),事情可能会变得复杂,但最多您可能会陷入无限循环。 (这并不好笑!)。如果你足够幸运没有进入循环,那么在某个时候回调数组被耗尽,然后就没有任何对回调列表的引用,所以它可以用于 GC。

但是。

如果你强制他们,事情可能会出错。

您可以在回调中使用 arguments.callee。

你也可以在键盘上泼啤酒。

如果你从 window 跳出去,除非你住在一楼,否则你很可能会受伤。

快乐的 EcmaScripting!

关于javascript - 这个 AJAX 模式是内存泄漏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16916163/

有关javascript - 这个 AJAX 模式是内存泄漏吗?的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  5. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  6. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  7. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  8. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  9. ruby - 这个 ruby​​ 注入(inject)魔术是如何工作的? - 2

    我今天看到了一个ruby​​代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem

  10. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

随机推荐