草庐IT

objective-c - 废弃内存和内存泄漏有什么区别?

coder 2023-07-27 原文

两者完全相同,只是“废弃内存”是指泄漏的整个对象图,而不仅仅是单个对象。正确的?

最佳答案

首先,您需要了解“内存对象图”或“应用程序对象图”(或者简单地说,“对象图”,因为它适用于分配的缓冲区)的概念。在这种情况下,“对象”指的是应用程序中的任何分配,无论是对象还是简单的 malloc() ed 缓冲区。如果任何对象都可以包含对其他对象的引用(指针),则为“图形”部分。

应用程序的“事件对象图”是可以从应用程序中的各种“根”直接或间接访问的所有分配。 “根”本身就是对对象的实时引用,而不管其他任何东西是否显式地引用了根。

例如,全局变量是根;通过引用一个对象,一个全局变量,根据定义,使该对象成为应用程序事件对象图的一部分。并且,通过暗示,全局变量引用的对象也被认为是事件的;没有泄露。

堆栈也是如此;任何线程的事件堆栈引用的任何对象本身都被认为是事件的。

考虑到这一点,泄漏被遗弃的内存实际上确实有两个不同的含义。

泄漏

泄漏是一 block 内存,没有来自应用程序事件对象图中任何事件对象的分配引用。

IE。内存无法访问,因此无法再次引用它(除非出现错误)。这是死内存。

请注意,如果对象 A 指向对象 B,对象 B 指向 A,但事件对象图中没有任何内容指向 A 或 B,则它仍然是泄漏。如果 B->A 和 A->B 引用都是保留引用,那么您将获得保留循环和泄漏。

被遗弃的内存

在应用程序的事件对象图中但由于应用程序逻辑问题而不再可访问的分配被视为已放弃,但未泄漏。

例如,假设您有一个缓存,其条目是 NSData 的实例。从某个 URL 下载的 URL 在 URL 中包含 session ID(一种常见模式),并且该 session ID + URL 用作在缓存中查找内容的键。现在,假设用户注销,导致 session ID 被破坏。如果缓存没有删除所有特定于该 session ID 的条目,那么所有这些 NSData对象将被丢弃,但不会泄露,因为它们仍然可以通过缓存访问。

实际上,在两者之间做出如此强烈的区分几乎没有用处,因为修复需要非常不同的策略。

修复泄漏是要找出额外保留的来源(或者在基于 free() 的泄漏的情况下,可能需要插入对 malloc() 的丢失调用)。由于无法从事件对象图中找到检测到的泄漏,因此修复泄漏真的很简单。

由于几个原因,修复废弃的内存可能相当棘手。

首先,内存仍然可以从事件对象图中访问。因此,根据定义,您的应用程序中存在保持内存事件的算法问题。发现和修复它通常比修复一个泄漏要困难得多,并且可能具有破坏性。

其次,可能存在对废弃分配的非归零非保留弱引用。也就是说,如果你弄清楚在哪里修剪强引用并让分配真正消失,那并不意味着你的工作已经完成;如果还有任何剩余的非归零弱引用,它们现在将是悬空指针和..... 繁荣 .

正如阿米特所说,Heapshot Analysis非常善于发现泄漏、废弃的内存以及——非常重要的——整体“不希望的内存增长”。

关于objective-c - 废弃内存和内存泄漏有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8840168/

有关objective-c - 废弃内存和内存泄漏有什么区别?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

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

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

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

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

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. 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

  6. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  7. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  8. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  9. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐