Objective-C自动引用计数和垃圾收集的区别是什么?

时间:2022-05-11 22:29:19

With the new automatic reference counting (ARC) introduced in Xcode 4.2, we no longer need to manually manage retain / release in Objective-C.

随着Xcode 4.2中引入的新的自动引用计数(ARC),我们不再需要在Objective-C中手动管理retain / release。

This seems similar to garbage collection, as done in Objective-C on the Mac, and in other languages. How does ARC differ from garbage collection?

这似乎与垃圾收集类似,在Mac上的Objective-C和其他语言中都是如此。ARC与垃圾收集有什么不同?

4 个解决方案

#1


58  

As I describe in my answer here, ARC can provide the best of both manual memory management and tracing garbage collection. It mostly removes the need for a developer to track manual retains, releases, and autoreleases on Objective-C objects, yet avoids the need for a garbage collector process which can use up limited resources on a mobile device and cause occasional stutters in a running application.

正如我在这里的回答中所描述的,ARC可以提供最好的手动内存管理和跟踪垃圾收集。它主要消除了开发人员跟踪Objective-C对象上的手动保存、发布和自动发送的需要,但也避免了垃圾收集器进程的需要,该进程可能会耗尽移动设备上有限的资源,并在运行中的应用程序中偶尔导致结巴。

ARC inserts the appropriate retains and releases required for reference counting at compile time, by applying the rules that all Objective-C developers have had to use over the years. This frees the developer from having to manage this themselves. Because the retains and release are inserted at compile time, no collector process is needed to continually sweep memory and remove unreferenced objects.

通过应用多年来所有Objective-C开发人员必须使用的规则,ARC在编译时插入引用计数所需的适当保留和发布。这使开发人员不必自己管理这些内容。因为在编译时插入了保留和释放,所以不需要任何收集器进程来持续地扫描内存并删除未引用的对象。

One slight advantage that tracing garbage collection has over ARC is that ARC will not deal with retain cycles for you, where tracing garbage collection can pick these up.

跟踪垃圾收集优于ARC的一个小优势是,ARC不会为您处理保留循环,在那里跟踪垃圾收集可以收集这些循环。

A great read on the subject comes from this thread on Apple's Objective-C mailing list, where Chris Lattner has this to say:

关于这个话题的一个很好的解读来自于苹果Objective-C邮件列表中的这个帖子,克里斯·拉特纳(Chris Lattner)说:

The primary advantage of GC over ARC is that it collects retain cycles. A secondary advantage is that "retained" assignments are "atomic" because they are a simple store. ARC has several big advantages over libauto GC:

GC优于ARC的主要优点是它收集保留循环。第二个好处是“保留”分配是“原子的”,因为它们是一个简单的存储。与libauto GC相比,ARC有几大优势:

  1. It has deterministic reclamation of objects (when the last strong reference to the object goes away) where GC frees an object "sometime later". This defines away a class of subtle bugs that can exist in GC apps that aren't exposed because the collector doesn't trigger "in the buggy window".
  2. 它具有对对象的确定性回收(当对对象的最后一个强引用消失时),GC将在“稍后”释放对象。这就消除了GC应用程序中可能存在的一种微妙的bug,因为收集器不会在“错误窗口”中触发这些bug。
  3. The high water mark is generally much lower with ARC than GC because objects are released sooner.
  4. 高水位标记通常比GC低得多,因为对象释放得更快。
  5. libauto provides a fragile programming model, you have to be careful to not lose write barriers etc.
  6. libauto提供了一个脆弱的编程模型,您必须小心不要丢失写障碍等。
  7. not all of the system frameworks are GC clean, and the frameworks do occasionally regress as they evolve.
  8. 并不是所有的系统框架都是GC clean的,而且随着框架的发展,这些框架有时也会倒退。
  9. ARC doesn't suffer from false roots. libauto conservatively scans the stack, which means that integers that look like pointers can root object graphs.
  10. 弧线没有假根。libauto保守地扫描堆栈,这意味着看起来像指针的整数可以根对象图。
  11. ARC doesn't have anything that kicks in and stops your app, causing UI stutters. libauto is pretty advanced as far as GC implementations go because it doesn't immediately stop every thread, but it still does usually end up stopping all the UI threads.
  12. ARC没有任何启动和停止你的应用程序的东西,导致UI结巴。libauto就GC实现而言是非常高级的,因为它不会立即停止每个线程,但它通常仍然会停止所有UI线程。

I am currently migrating both my manually memory managed projects, as well as those using Objective-C garbage collection, to ARC. After using garbage collection in a couple of Mac applications for a while now, I see some significant advantages in moving these projects to ARC.

我目前正在将我的手动内存管理项目以及使用Objective-C垃圾收集的项目迁移到ARC。在几个Mac应用程序中使用垃圾收集之后,我发现将这些项目迁移到ARC有一些显著的优势。

#2


11  

ARC rely on a compile time "referenced" objects which make it efficient in a low-power mode environments (Mobile devices).

ARC依赖于编译时“引用”对象,这些对象使它在低功耗模式环境(移动设备)中更高效。

GC rely on a runtime based "reachable" objects which make it efficient in a multi-threaded environment.

GC依赖于基于运行时的“可访问”对象,这些对象使它在多线程环境中更有效。

Operation

ARC injects a code into the executable to be executed "automatically" on unused objects depending on their reference count.

ARC将代码注入可执行文件中,以根据未使用对象的引用计数“自动”执行。

GC works in the runtime as it will detect the unused object graphs (will eliminate retain-cycles) and remove them on an indeterminate time intervals

GC在运行时中工作,因为它将检测未使用的对象图(将消除保留周期)并以不确定的时间间隔删除它们

Advantages of Automatic Reference Counting

  • Real-time, deterministic destruction of objects as they become unused.
  • 当对象不再使用时,对其进行实时、确定性的破坏。
  • No background processing.
  • 没有后台处理。

Advantages of Garbage Collection

  • GC can clean up entire object graphs, including retain cycles.
  • GC可以清理整个对象图,包括保留周期。
  • GC proceed in the background, so less memory management work is done as part of the regular application flow.
  • GC在后台进行,因此在常规应用程序流中完成的内存管理工作较少。

Disadvantages of Automatic Reference Counting

  • ARC cannot handle retain cycles automatically.
  • 电弧不能自动处理保留周期。

Disadvantages of Garbage Collection

  • Because GC happens in the background, the exact time frame for object releases is undetermined.
  • 因为GC发生在后台,所以对象释放的确切时间框架是未知的。
  • When a GC happens, other threads in the application may be temporarily put on hold.
  • 当GC发生时,应用程序中的其他线程可能被暂时搁置。

#3


7  

How does ARC differ from garbage collection?

ARC与垃圾收集有什么不同?

ARC is a form of garbage collection.

ARC是垃圾收集的一种形式。

You probably mean "what is the difference between ARC and tracing garbage collection (like the JVM and .NET)?". The main differences are that ARC is slower and leaks cycles. That's why the JVM and .NET both use tracing garbage collectors. For more information, please read How do reference counting and tracing garbage collection compare?.

您可能想问“ARC和跟踪垃圾收集之间的区别是什么(比如JVM和。net)?”主要的不同之处在于电弧变慢和泄漏循环。这就是为什么JVM和。net都使用跟踪垃圾收集器。有关更多信息,请阅读参考计数和跟踪垃圾收集的比较?

#4


-6  

the short and sweet answer is as follow:

简短而甜蜜的回答如下:

GC of java is Runtime, while ARC is compile time.

java的GC是运行时,而ARC是编译时。

GC has reference to the objects at runtime and check for the dependencies of object runtime. While ARC appends the release, retain, autorelease calls at compiletime.

GC在运行时引用对象并检查对象运行时的依赖关系。当ARC附加发布、保留、自动发送在编译时调用。

#1


58  

As I describe in my answer here, ARC can provide the best of both manual memory management and tracing garbage collection. It mostly removes the need for a developer to track manual retains, releases, and autoreleases on Objective-C objects, yet avoids the need for a garbage collector process which can use up limited resources on a mobile device and cause occasional stutters in a running application.

正如我在这里的回答中所描述的,ARC可以提供最好的手动内存管理和跟踪垃圾收集。它主要消除了开发人员跟踪Objective-C对象上的手动保存、发布和自动发送的需要,但也避免了垃圾收集器进程的需要,该进程可能会耗尽移动设备上有限的资源,并在运行中的应用程序中偶尔导致结巴。

ARC inserts the appropriate retains and releases required for reference counting at compile time, by applying the rules that all Objective-C developers have had to use over the years. This frees the developer from having to manage this themselves. Because the retains and release are inserted at compile time, no collector process is needed to continually sweep memory and remove unreferenced objects.

通过应用多年来所有Objective-C开发人员必须使用的规则,ARC在编译时插入引用计数所需的适当保留和发布。这使开发人员不必自己管理这些内容。因为在编译时插入了保留和释放,所以不需要任何收集器进程来持续地扫描内存并删除未引用的对象。

One slight advantage that tracing garbage collection has over ARC is that ARC will not deal with retain cycles for you, where tracing garbage collection can pick these up.

跟踪垃圾收集优于ARC的一个小优势是,ARC不会为您处理保留循环,在那里跟踪垃圾收集可以收集这些循环。

A great read on the subject comes from this thread on Apple's Objective-C mailing list, where Chris Lattner has this to say:

关于这个话题的一个很好的解读来自于苹果Objective-C邮件列表中的这个帖子,克里斯·拉特纳(Chris Lattner)说:

The primary advantage of GC over ARC is that it collects retain cycles. A secondary advantage is that "retained" assignments are "atomic" because they are a simple store. ARC has several big advantages over libauto GC:

GC优于ARC的主要优点是它收集保留循环。第二个好处是“保留”分配是“原子的”,因为它们是一个简单的存储。与libauto GC相比,ARC有几大优势:

  1. It has deterministic reclamation of objects (when the last strong reference to the object goes away) where GC frees an object "sometime later". This defines away a class of subtle bugs that can exist in GC apps that aren't exposed because the collector doesn't trigger "in the buggy window".
  2. 它具有对对象的确定性回收(当对对象的最后一个强引用消失时),GC将在“稍后”释放对象。这就消除了GC应用程序中可能存在的一种微妙的bug,因为收集器不会在“错误窗口”中触发这些bug。
  3. The high water mark is generally much lower with ARC than GC because objects are released sooner.
  4. 高水位标记通常比GC低得多,因为对象释放得更快。
  5. libauto provides a fragile programming model, you have to be careful to not lose write barriers etc.
  6. libauto提供了一个脆弱的编程模型,您必须小心不要丢失写障碍等。
  7. not all of the system frameworks are GC clean, and the frameworks do occasionally regress as they evolve.
  8. 并不是所有的系统框架都是GC clean的,而且随着框架的发展,这些框架有时也会倒退。
  9. ARC doesn't suffer from false roots. libauto conservatively scans the stack, which means that integers that look like pointers can root object graphs.
  10. 弧线没有假根。libauto保守地扫描堆栈,这意味着看起来像指针的整数可以根对象图。
  11. ARC doesn't have anything that kicks in and stops your app, causing UI stutters. libauto is pretty advanced as far as GC implementations go because it doesn't immediately stop every thread, but it still does usually end up stopping all the UI threads.
  12. ARC没有任何启动和停止你的应用程序的东西,导致UI结巴。libauto就GC实现而言是非常高级的,因为它不会立即停止每个线程,但它通常仍然会停止所有UI线程。

I am currently migrating both my manually memory managed projects, as well as those using Objective-C garbage collection, to ARC. After using garbage collection in a couple of Mac applications for a while now, I see some significant advantages in moving these projects to ARC.

我目前正在将我的手动内存管理项目以及使用Objective-C垃圾收集的项目迁移到ARC。在几个Mac应用程序中使用垃圾收集之后,我发现将这些项目迁移到ARC有一些显著的优势。

#2


11  

ARC rely on a compile time "referenced" objects which make it efficient in a low-power mode environments (Mobile devices).

ARC依赖于编译时“引用”对象,这些对象使它在低功耗模式环境(移动设备)中更高效。

GC rely on a runtime based "reachable" objects which make it efficient in a multi-threaded environment.

GC依赖于基于运行时的“可访问”对象,这些对象使它在多线程环境中更有效。

Operation

ARC injects a code into the executable to be executed "automatically" on unused objects depending on their reference count.

ARC将代码注入可执行文件中,以根据未使用对象的引用计数“自动”执行。

GC works in the runtime as it will detect the unused object graphs (will eliminate retain-cycles) and remove them on an indeterminate time intervals

GC在运行时中工作,因为它将检测未使用的对象图(将消除保留周期)并以不确定的时间间隔删除它们

Advantages of Automatic Reference Counting

  • Real-time, deterministic destruction of objects as they become unused.
  • 当对象不再使用时,对其进行实时、确定性的破坏。
  • No background processing.
  • 没有后台处理。

Advantages of Garbage Collection

  • GC can clean up entire object graphs, including retain cycles.
  • GC可以清理整个对象图,包括保留周期。
  • GC proceed in the background, so less memory management work is done as part of the regular application flow.
  • GC在后台进行,因此在常规应用程序流中完成的内存管理工作较少。

Disadvantages of Automatic Reference Counting

  • ARC cannot handle retain cycles automatically.
  • 电弧不能自动处理保留周期。

Disadvantages of Garbage Collection

  • Because GC happens in the background, the exact time frame for object releases is undetermined.
  • 因为GC发生在后台,所以对象释放的确切时间框架是未知的。
  • When a GC happens, other threads in the application may be temporarily put on hold.
  • 当GC发生时,应用程序中的其他线程可能被暂时搁置。

#3


7  

How does ARC differ from garbage collection?

ARC与垃圾收集有什么不同?

ARC is a form of garbage collection.

ARC是垃圾收集的一种形式。

You probably mean "what is the difference between ARC and tracing garbage collection (like the JVM and .NET)?". The main differences are that ARC is slower and leaks cycles. That's why the JVM and .NET both use tracing garbage collectors. For more information, please read How do reference counting and tracing garbage collection compare?.

您可能想问“ARC和跟踪垃圾收集之间的区别是什么(比如JVM和。net)?”主要的不同之处在于电弧变慢和泄漏循环。这就是为什么JVM和。net都使用跟踪垃圾收集器。有关更多信息,请阅读参考计数和跟踪垃圾收集的比较?

#4


-6  

the short and sweet answer is as follow:

简短而甜蜜的回答如下:

GC of java is Runtime, while ARC is compile time.

java的GC是运行时,而ARC是编译时。

GC has reference to the objects at runtime and check for the dependencies of object runtime. While ARC appends the release, retain, autorelease calls at compiletime.

GC在运行时引用对象并检查对象运行时的依赖关系。当ARC附加发布、保留、自动发送在编译时调用。