Objective-C的内存管理(1)——内存管理概述

栏目: Objective-C · 发布时间: 4年前

内容简介:应用程序开发中,内存管理是个重要的话题。简单而言,语言层面的内存管理基本有三类:如C和曾经的C++。

概述

应用程序开发中,内存管理是个重要的话题。

简单而言,语言层面的内存管理基本有三类:

1. 纯粹的手动管理

如C和曾经的C++。

char *some_string = malloc(BUFFER_SIZE);
// do something
free(some_string);

这个简单的例子里用完就释放还好,但是有时候这个some_string被传来传去不知道飞哪儿去了,就比较尴尬。

纯手动管理的代价是 程序员 的心智负担比较重。

即使后来C++程序员们抽象出RAII这样的实践规范,一定程度上降低了管理的复杂度,但是相对来说成本还是略高。

随着语言的发展,已经很少有语言只依赖手动管理内存了。

2. 基于某些机制实现半自动管理

这里的某些机制其实通常就是引用计数。毕竟这是最简单的内存管理辅助手段。

引用计数是计算机编程语言中的一种内存管理技术,是指将资源(可以是对象、内存或磁盘空间等等)的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。

引用计数大家都了解,不多说,单纯的自动使用引用计数问题在于无法解决循环引用的问题。很多语言选择让程序员付出一点劳动来解决这个问题。

早年,Objc选择的是退一步,完全让程序员来管理引用计数的加减,称为MRC,显然管理成本偏高。后来推出了ARC,提供了更健全的机制,程序员只要标识出对象间的引用关系是强引用还是弱引用就可以了,大大降低了程序员的负担。

虽然走这个路子的语言不算多,但除了Objc之外还是有好几个的。

C++的智能指针跟Objc的ARC就比较相似。而 Rust的所有权模型 本质上也是类似的。

3. 自动垃圾回收

通过GC自动管理内存大概是现在的主流了。对程序员来讲实在是太舒适了,开发时几乎不用考虑内存管理的问题。Java、JavaScript、 Pythongo 等一大票语言都是走的这条路。

GC是基于可达性分析算法的,即,从根节点(全局变量、局部变量等等)出发,遍历引用到的对象,所有没遍历到的对象就可以释放了。

当然从原理到实际应用中间差了十万八千里。朴素的GC会经常造成Stop The World。一旦Stop-the-world发生,除了GC所需的线程外,其他线程都将停止工作,中断了的线程直到GC任务结束才继续它们的任务。

于是很多GC算法被发明出来用于优化、减少。常见的CMS、G1回收算法都极大地减少了STW的时间,但仍然不能完全避免。

R大在 Java 大内存应用(10G 以上)会不会出现严重的停顿? 中提到Zing JVM采用的C4算法是可以完全避免STW的,不过看起来为了避免STW,C4算法会吃掉更多的内存,程序吞吐量会受到影响。

小结

总结一下吧,纯手动管理基本上已被淘汰,ARC(暂且把方法二这类都称为ARC吧)和GC对比之下,

对开发者,ARC需要程序员付出一定的代价进行管理,GC则基本上完全解放双手;

性能上,GC通常会造成STW现象,对响应时间比较敏感的程序,比如高频交易系统,是很难接受的,而ARC不会对性能造成明显影响。

几点有趣的事情

1. 总体性能

总体性能上,只要不是内存跑得特别满,ARC的总体代价是高于GC的。其实想想就知道了,GC只关注两次回收间的变化,而ARC要对每一次引用的改变进行计数,总体性能上比GC差是很正常的,但由于ARC的耗时是均匀分布在运行时间里的,通常我们不用很关注。关于这个问题可以参考 这篇论文

2. cpython的方案

另外比较特别的是,Python的默认解释器CPython中应用了引用计数与垃圾回收相结合的手法,没有循环引用的对象会被引用计数回收,剩下的交给GC处理,大大降低了GC的压力。感觉很有意思。

3. ARC的性能

在类ARC方案上,C++提供的能力是比较全面的。这可能跟c++常用于一些性能比较苛刻的场景有关。

出于性能原因,使用c++智能指针时有如下指导思想:

  1. 对象的所有权不重要时 ,用裸指针
  2. 对象的所有权唯一时,用unique_ptr,能用unique_ptr就不要用shared_ptr。
  3. 要处理复杂情况时,可以使用shared_ptr,但需要注意不要滥用。当引用关系不影响所有权时,用weak_ptr。

Rust也有类似的能力。

而python和Objective-C就没有这么多讲究,所有的引用计数其实都是shared_ptr。Objc在iOS上这么多年,而后来的swift也传承了ARC,基本上可以认为,移动端应用从小到大都不差这么一丢丢性能。

以此推论,绝大部分c++应用也完全没必要关注这几个指针间的差异,操起shared_ptr就是干。


以上所述就是小编给大家介绍的《Objective-C的内存管理(1)——内存管理概述》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Design systems

Design systems

Not all design systems are equally effective. Some can generate coherent user experiences, others produce confusing patchwork designs. Some inspire teams to contribute to them, others are neglected. S......一起来看看 《Design systems》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具