内存管理相关

2020-09-27  本文已影响0人  ruiying
内存管理相关面试题

一· 使用CADisplayLink,NSTimer有什么注意点?

其中创建定时器的方式有:NSTimer,CADisplayLink(可以用在卡顿检测(检测应用程序的帧率)及自定义动画中,它的调用频率和设备屏幕刷新频率一致),GCD(更加准时,因为它不依赖与runloop,直接基于内核实现,更加高效)
答:(1)循环引用问题 (2)不准时的问题(runloop跑圈执行时间问题和runloop模式问题,default模式下滚动视图滚动的时候会影响到定时器)

截屏2019-12-11下午6.05.54.png
解决方式
其实创建中间对象直接继承于NSProxy就行,NSProxy和NSObject是平级的,用它做消息转发的话 省掉了方法动态解析的这个流程。所以直接用它就行了
截屏2019-12-11下午7.31.15.png
问题一解决方案
建议使用GCD定时器!因为NSTimer和CADisplayLink都依赖于runloop,而runloop就是不停的跑圈,每跑一圈检查一下累计的时间,每次任务可能不一样那么跑完一圈花费的时间也不一样,比如这次跑完一圈0.7秒还没到一秒不执行定时器的方法,继续跑下一圈恰巧这圈任务较重 跑了0.4秒 这个时候再去执行定时器的方法就慢了,所以就不准确了。而GCD创建的定时器是不依赖于runloop的 是直接和系统内核挂钩的,所以也不会受滚动视图的影响
销毁timer的方式

[图片上传中...(image.png-3b932-1586956747605-0)]
二· 介绍下内存的几大区域
地址由低到高内存布局为:保留内存--代码段--数据段(数据段里依次是字符串常量,已初始化数据,未初始化数据)--堆区--栈区--内存区。
堆区(heap)一般由程序员分配释放
栈区(stack)— 由编译器自动分配释放

1、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3、全局(静态)区包含下面两个分区:

数据区:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。
BSS区:BSS段包含了程序中未初始化全局变量。
4、文字常量区 —常量字符串就是放在这里的。程序结束后由系统释放。

5、程序代码区—存放函数体的二进制代码。

iOS程序的内存布局。 注意:堆空间地址分配是越来越大就是由低到高(记忆辅助:堆需要一点一点堆大,所以地址分配是越来越大),而栈空间是由高到低
内存布局:栈区:存储局部变量(不包含字符串常量),在作用域结束后内存会被回收

三· 讲一下你对iOS内存管理的理解

内存管理 weak和__unsafe__unretained都是弱引用,但是weak所指向内存被释放之后,weak所修饰的对象会自动置为nil;而 __unsafe__unretained ,assign修饰的会仍然指向原对象的内存地址,变成野指针。注意野指针不一定崩溃的,就比如if(person3)不会崩,若打印内存地址就会崩溃或者调用isKindof会崩溃

四· autorelease对象在什么时机会被调用release?

截屏2019-12-12下午10.05.54.png
截屏2019-12-12下午10.33.21.png

方法里有局部对象,出了方法后会被立即释放吗?

iOS系统在运行程序时,会自动创建一些线程,⚠️每个线程都默认拥有自动释放池。一个线程对应一个runloop(解释在runloop的模式里,有default和tracking,而commons相对与一个几何,一个线程对应唯一一个runloop,commons的模式其实时按照设定的标志符区切换的)

答:分两种情况:
(1)(不分ARC还是MRC)

自动释放池是怎么管理对象的?


截屏2019-12-19上午3.46.47.png 截屏2019-12-19上午3.45.26.png
截屏2019-12-19上午3.45.41.png

五.内存泄漏问题

ARC虽然可以帮助开发者解决大部分内存管理问题,但对内存泄漏仍然束手无策。

5.1 内存泄漏的核心问题是循环引用,那么循环引用的场景都有哪些呢?
5.1.1 重点说一下performSelector...delay...造成的内存泄漏

问题描述:testPerformSelectorFunc在viewDidDisappear之后执行,也就是在页面返回disappear以后,dealloc方法并没有执行,控制器对象并没有真正销毁,造成了内存泄漏。而等达到10s时间的时候,虽然该控制器已经disappear了,但还会执行该页面的代码testPerformSelectorFunc方法,执行完这个方法,才执行了dealloc方法,对象才得到了释放,证明执行完performSelector方法后self.retainCount会对应减少(个人理解:点击POP之后,也就是说如果func方法还没执行,那么不会走dealloc方法,self不会释放,当执行完这个方法之后才会调用dealloc,对象才能真正被释放)。

[NSObject cancelPreviousPerformRequestsWithTarget:self]

- 内存泄漏和内存溢出的区别?就是内存溢出是内存不够,常见的就是数组越界,就比如存一个long大的数,却给了一个int类型的存储空间。如果内存泄漏不注意,有可能导致内存溢出,因为大量的对象不被释放,存在内存中,会占用越来越多的空间

6.创建大量临时自动释放对象 造成内存爆增现象

问题?:不加自动释放池的话,V啥时候释放呢?

这也解释了,为什么要用autorelease,它可以优化内存,因为系统的自动释放池会在每次事件循环结束后清空,发送release
上一篇 下一篇

猜你喜欢

热点阅读