推广

内存管理面试题

iseeyu2年前 (2024-02-22)推广147

截屏2021-07-15 下午2.01.30.png

ARC 的 retainCount 怎么存储的?

存在64张哈希表中,根据哈希算法去查找所在的位置,无需遍历,十分快捷
散列表(引用计数表、weak表)
SideTables 表在 非嵌入式的64位系统中,有 64张 SideTable 表
每一张 SideTable 主要是由三部分组成。自旋锁、引用计数表、弱引用表。
全局的 引用计数 之所以不存在同一张表中,是为了避免资源竞争,解决效率的问题。
引用计数表 中引入了 分离锁的概念,将一张表分拆成多个部分,对他们分别加锁,可以实现并发操作,
提升执行效率
引用计数表(哈希表)
通过指针的地址,查找到引用计数的地址,大大提升查找效率
通过 DisguisedPtr(objc_object) 函数存储,同时也通过这个函数查找,这样就避免了循环遍历。

什么是 ARC?

ARC 是 iOS 5 引入的内存管理新功能 -- 自动引用计数 。它的工作原理大致是这样:当我们编译源码时,编译器会分析源码
中每个对象的生命周期,然后基于这些对象的生命周期,来添加相应的引用计数操作代码。所以,ARC 是工作在编译期的一种技术方案。

这样的好处是:编译之后,ARC 与非 MRC 代码是没有什么差别的,所以二者可以在源码中共存。实际上,你可以通过编译
参数 -fno-objc-arc 来关闭部分源代码的 ARC 特性。由于 ARC 能够深度分析每一个对象的生命周期,它能够做到比 MRC 更加高效。
例如在一个函数中,对一个对象刚开始有一个引用计数 +1 的操作,之后又紧接着有一个 -1 的操作,那么编译器就可以把这两个操作都优化掉。

ARC 的核心思想?

* 自己生成的对象,自己持有
* 非自己生成的对象,自己可以持有
* 自己持有的对象不再需要时,需要对其进行释放
* 非自己持有的对象无法释放

ARC 在使用时应该遵循的原则?

* 不能使用 retain、release、retainCount、autorelease。
* 不可以使用 NSAllocateObject、NSDeallocateObject。
* 必须遵守内存管理方法的命名规则。
* 不需要显示的调用 Dealloc。
* 使用 @autoreleasePool 来代替 NSAutoreleasePool。
* 不可以使用区域 NSZone。
* 对象性变量不可以作为 C 语言的结构体成员。
* 显示转换 id 和 void*。

ARC 在编译时做了哪些工作?

* 自动调用 保留(retain) 与 释放(release) 的方法
* 相对于垃圾回收这类内存管理方案,ARC 不会带来运行时的额外开销,所以对于应用的运行效率不会有影响。 ARC 会把能够互相抵消 retain、release、autorelease,操作简化,如果发现在同一个对象上执行了多次保留与释放操作,那么 ARC 有时可以成对的移除这两个操作。

简要阐述内存相关的关键字?

Strong
Strong 修饰符表示指向并持有该对象,其修饰对象的引用计数会加1。该对象只要引用计数不为0就不会被销毁。当然可以通过将变量强制赋值 nil 来进行销毁。
Weak
weak 修饰符指向但是并不持有该对象,引用计数也不会加1。在 Runtime 中对该属性进行了相关操作,无需处理,可以自动销毁。weak用来修饰对象,多用于避免循环引用的地方。weak 不可以修饰基本数据类型。
assign
assign主要用于修饰基本数据类型,例如NSInteger,CGFloat,存储在栈中,内存不用程序员管理。assign是可以修饰对象的,但是会出现问题。
copy
copy关键字和 strong类似,copy 多用于修饰有可变类型的不可变对象上 NSString,NSArray,NSDictionary上。
__unsafe_unretain
__unsafe_unretain 类似于 weak ,但是当对象被释放后,指针已然保存着之前的地址,被释放后的地址变为 僵尸对象,访问被释放的地址就会出问题,所以说他是不安全的。
__autoreleasing
将对象赋值给附有 __autoreleasing修饰的变量等同于 ARC 无效时调用对象的 autorelease 方法,实质就是扔进了自动释放池。

说一下什么是悬垂指针?什么是野指针?

悬垂指针
指针指向的内存已经被释放了,但是指针还存在,这就是一个 悬垂指针 或者说 迷途指针
野指针
没有进行初始化的指针,其实都是 野指针

内存管理默认的关键字?

MRC
@property (atomic,readwrite,retain) NSString *name;
ARC
@property (atomic,readwrite,strong) NSString *name;

__weak 和 __unsafe_unretain 的区别?

__weak 是 __unsafe_unretain升级版,__unsafe_unretain 在指向的内存地址销毁后,指针本身并不会自动销毁,这也就造成了野指针,之后容易造成 Crash。__weak 在指向的内存销毁后,可以将指针变量置为 nil,这样更加安全。

__weak 修饰的变量在地址被释放后,为何被置为 nil?

在 Runtime 中专门维护了一个用于存储 weak指针变量的 weak 表,这实际上是一个 Hash 表。这个表 key 是 weak指针 所指向的内存地址,value 是指向这个内存地址的所有 weak指针,实际上是一个数组。
过程可以总结为3步
* 1、初始化时:runtime 会调用 objc_initWeak 函数,初始化一个新的 weak指针 指向对象的地址。
* 2、添加引用时:objc_initWeak函数会调用 objc_storeWeak() 函数, objc_storeWeak()的作用是更新指针指向,创建对应的弱引用表。
* 3、释放时,调用 clearDeallocating 函数。clearDeallocating 函数首先根据对象地址获取所有 weak指针 地址的数组,然后遍历这个数组把其中的数据设为 nil,最后把这个 entry 从weak表 中删除,最后清理对象的记录。

为什么在 MRC 已经有 __weak 的情况下,还需要 _unsafe_unretain。?

* 兼容性考虑。iOS4 以及之前还没有引入 weak,这种情况想表达弱引用的语义只能使用 unsafe_unretained。这种情况现在已经很少见了。
* 性能考虑。使用 weak 对性能有一些影响,因此对性能要求高的地方可以考虑使用 unsafe_unretained 替换 weak。一个例子是 YYModel 的实现,为了追求更高的性能,其中大量使用 unsafe_unretained 作为变量标识符。

如何打破循环引用?

* 注意变量作用域,使用 autorelease 让编译器来处理引用。
* 使用弱引用(__weak)。
* 当实例变量完成工作后,将其置为 nil。

能不能用 assign 修饰 NSObject 类型?

也可以,但有可能出问题。
使用 assign 修饰 NSObject 类型,赋值之后会被立即释放,对应的属性也就变成了野指针。
运行时跑到属性有关操作会直接崩溃掉。

autoreleasePool 什么时候释放?

App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()。
第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是 -2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。
第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠) 时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后。
在主线程执行的代码,通常是写在诸如事件回调、Timer回调内的。这些回调会被 RunLoop 创建好的 AutoreleasePool 环绕着,所以不会出现内存泄漏,开发者也不必显示创建 Pool 了。

alloc/init和New区别

第一种方式(alloc init)来创建对象时,系统首先会给变量分配内存,然后调用init方法来进行初始化,或者调用initWith方法来初始化。
第二种方式(new)是第一种方式中两步的综合,系统会直接开辟好内存,调用init方法来初始化对象,但是只能调用init方法。

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/55847.html

相关文章

学习富人的九大特征,避开穷人最可怕的八种思维,

学习富人的九大特征,避开穷人最可怕的八种思维,

即便是你的兄弟姐妹也会和你也会表现出不同的区别,然后试着将这个问题放大来看,通过下面的对比图来看看穷人和富人的思维区别。穷人思维是指与富人不同的对待事物的态度和思维方式,主要表现为不上进、不善思、鼠目寸光,只看眼前利益,不懂得感恩和互赢,其不是说穷人脑子里拥有的思维。有这种...

淘宝店铺可以转让给别人吗(淘宝网店可以转让给别人吗?)

淘宝店铺可以转让给别人吗(淘宝网店可以转让给别人吗?)

当然是可以的,现在淘宝店铺允许协议过户,只要在卖家中心提交协议过户申请,审核通过之后就能彻底转让出去了,而且很多商家都愿意购买淘宝店铺来经营,因为出售的店铺都会有一定的经营基础,不需要花费很多精力去做初步运营,很实惠。那所有的店铺都能出售吗?...

小心“拼多多砍价”背后的陷阱,别让银行卡被盗!

小心“拼多多砍价”背后的陷阱,别让银行卡被盗!

随着社交电商平台拼多多的火热,越来越多的人加入了“拼多多砍价”的行列。然而,这个看似优惠的活动却暗藏着危机,银行卡被盗的案例屡见不鲜。本文将为大家揭示其中的风险,并提供一些防范建议,让你的钱包更安全。 我们要认清拼多多砍价的本质。拼多多砍价其实是一种营销手段,商家通过提供部分优惠,吸...

什么叫反向链接。

什么叫反向链接。

经常听到大家在答疑论坛里说反向链接多么重要,但我一头雾水,到底什么是反向链接? 看以上这行内容中,“seo培训”这几个字链接指向了http://seo.aizhan.com。这个链接我们称为 直接链接。 对于答疑论坛来讲,这个链接是它的反向链接。 简单概括如下: 网页A 上有一个链接指向网页B,则网...

结合百度搜索引擎规则,网站优化公司总能在seo算法中找到出路。

结合百度搜索引擎规则,网站优化公司总能在seo算法中找到出路。

百度排名优化需要我们对搜索引擎进行深入的研究和调查。随着各大搜索引擎算法的调整,到底发生了什么?如今,搜索引擎完成了快捷、准确的处理功能,以满足用户的搜索习惯和体验要求。显然,如果要做百度优化,就要讨论这些算法的一些规律,而百度优化人员也需要不时地提升自己的技能,加入到搜索引擎的转型中来,然后真正做...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片