IOS性能优化之内存管理与内存爆增(一)

news/2024/11/6 15:26:08/

        在IOS程序中,内存通常被分成如下5个区域

        栈区:存储局部变量,在作用域结束后内存会被回收

        堆区:存储Objective-C对象,需要开发者手动申请和释放

        BSS区:用来存储未初始化的全局变量和静态变量

        数据区:用来存储已经初始化的全局变量、静态变量和常量

        代码段:加载代码

        在上面的五个内存区域中,除了堆区需要开发者手动进行内存管理外,其它区都由系统自动进行回收。

一 MRC下的内存管理

        MRC内存管理下的两条准则:

        谁持有对象,谁负责对象,不是自己持有的不能释放

        当对象不再需要时,需要主动释放。

        不是自己创建的对象,如果自己对其使用了强引用,那么也需要对其负责进行释放。在Objective-C中,下边中的方法,都会对对象进行持有:

        需要注意的是,前四个方法都是创建新的对象,让其引用计数为1,retain方法的作用是对当前对象进行持有,使其引用计数加1。

        当我们使用[self.view addSubview:v]时,self.view会对v强引用一次,v的引用计数会+1.当self.view被释放时,v也会被释放一次,引用计数会-1。

        当我们使用NSArray * array = @[obj]时,array会对obj强引用一次,obj的引用计数会+1,当array被释放时,obj也会被释放一次,引用计数会-1。

二 ARC下的内存管理

        在ARC下,有几个修饰关键字非常重要,分别是:__strong、__weak、__unsafe_unretained、__autoreleasing.这些关键字在ARC中被称为所有权修饰符

1 关于__strong

        实际上我们使用的指针默认都是__strong关键字修饰的,在ARC环境中,下面两行代码的意义完全一致:

        __strong NSArray * v = [NSArray array];

        NSArray * v2 = [NSArray array];

__strong修饰符通常用来对变量进行强引用,主要有以下三个作用:

        使用__strong修饰的变量如果是自己生成的,则会被添加进自动释放池,在作用域结束后,会被release一次。

        使用__strong修饰的变量如果不是自己生成的,则会被强引用,即会被持有使其引用计数+1,在离开作用域后会被release一次。

        使用__strong修饰的变量指针如果重新赋值或者置为nil,则变量会被release一次。

2 关于__weak

        __weak修饰符通常用来对变量进行弱引用,其最大的用途是避免ARC环境下的循环引用。__weak主要有以下两个作用:

        被__weak修饰的变量仅提供弱引用,不会使其引用计数增加。变量对象如果是自己生成的,则会被添加到自动释放池,会在离开作用域时被release一次,如果不是自己生成的,则离开作用域后,不会进行release操作。

        被__weak修饰的变量指针,变量如果失效,则指针会被自动置为nil,这时一种比较安全的设计方式,大量的减少了野指针造成的异常。

3 关于__unsafe_unretained

        从名字可以看出,这个修饰符是不安全的,和上面__weak修饰符相比,这个修饰符的作用也是对对象进行弱引用,不同的是,当变量对象失效时,其指针不会被自动置为nil。

__unsafe_unretained作用如下:

        被__unsafe_unretained修饰的变量仅提供弱引用,不会使其引用计数增加。变量对象如果是自己生成的,则会在离开作用域时被release一次,如果不是自己生成的,则在离开作用域后,不会进行release操作。

        当变量失效后,被修饰指针不会被安全处理为nil,即旧地址依然保存。

4 关于__autoreleasing

        __sutoreleasing修饰符常与自动释放池一起使用。

5 ARC环境下的几条原则

        不能使用retain、release、autorelease函数

        不能调用dealloc函数,可以覆写dealloc函数,但是十几种不可调用[super dealloc];

        不能使用NSAutoreleasePool,但可以使用@autoreleasepool代替。

        对象型变量不能作为C语言的结构体。

二 属性修饰符

        内存管理相关属性修饰符列举如下表:

三 自动释放池

        ios系统在运行应用程序时,会自动创建一些线程,每一个线程都默认拥有自动释放池。在每次执行时间循环结束之前,系统都会将其自动释放池清空。因此,大多数情况下,开发者都不必手动创建自动释放池,但有一种情况例外:

        如果在大量的循环中生成自动释放对象,则可能会导致内存消耗瞬间暴涨,当所有循环结束后,内存又急剧下降。这样的场景下使用AutoreleasePool进行优化内存:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//使用AutoreleasePool[self useAutoreleasePool];
}
#pragma 使用AutoreleasePool
-(void)useAutoreleasePool
{int n = 100000;for (int i = 0; i < n; i++) {UIView * v = [[UIView alloc] init];v.backgroundColor = [UIColor blueColor];UIImage * image = [UIImage imageNamed:@"yyll_gift_tz"];NSLog(@"i = %d", i);}
}

下图为检测的cpu的使用情况:

         可以看到Thread1占用的cpu内存爆增,内存的峰值达到76%.这样的场景适合使用AutoreleasePool,下面是优化后的代码:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//使用AutoreleasePool[self useAutoreleasePool];
}#pragma 使用AutoreleasePool
-(void)useAutoreleasePool
{int n = 100000;for (int i = 0; i < n; i++) {@autoreleasepool {UIView * v = [[UIView alloc] init];v.backgroundColor = [UIColor blueColor];UIImage * image = [UIImage imageNamed:@"yyll_gift_tz"];}NSLog(@"i = %d", i);}
}

 优化后检测到的cpu的使用情况如下:

可以看到内存的峰值降低了近10%,最高峰值为68%,且运行的时间从1min 29sec降至52sec。 

        

********* 内容源于 <<IOS性能优化实战>>*********


http://www.ppmy.cn/news/806864.html

相关文章

显卡ai性能测试软件,超频性能测试:TDP限制严重

RTX 2070 Founders Edition超频性能测试&#xff1a; 测过一轮的RTX 2080 Ti、RTX 2080显卡后发现&#xff0c;Turing显卡超频并不容易&#xff0c;主要是GPU BOOST 4.0频率提升更加恐怖以外&#xff0c;NVIDIA提供的OC SCAN API功能虽然方便&#xff0c;但终会有小问题&#x…

解决intel九代处理器黑苹果明明已经开启核显加速仍然出现各种问题

起因 因为工作需要配置了一台i5 9500带核显版本32G内存2666铭瑄2304巨无霸rx580&#xff0c;使用mac系统的final cut pro x莫名其妙出错退出。 开始也没有在意&#xff0c;因为并不是专业用&#xff0c;通过VideoProc软件测试&#xff0c;确定核显加速已经开启。 也就没有在意…

iOS_Memory Leak 内存泄露治理

文章目录 1、内存分类2、Memory Report3、Analyze4、Leaks4.1、前置设置4.2、页面介绍4.3、使用4.3.1、Leaks 页面4.3.2、Cycles & Roots页面4.3.3、Call Tree页面 5、Memory Graph5.1、前置设置5.2、入口&#xff1a;5.3、使用分析&#xff1a;5.3.1、分析方式1&#xff1…

内存超频会损坏内存吗 内存超频开不了机如何解决

对于硬件入门爱好者&#xff0c;常常有内存超频会损坏内存吗&#xff1f;内存超频开不了机如何解决的问题。笔者建议首先用户需要对超频后的风险有心理预期&#xff0c;超频是可能造成硬件损坏的&#xff0c;或者降低硬件的使用寿命&#xff0c;用户要根据自身需求考虑是否有超…

cpu飙高1000,几近崩溃

最近在做一个定时任务的项目&#xff0c;项目上线后。过段时间发现cpu不断飙高&#xff0c;10%,20%,30%,50%,70%,80%还再继续往上涨&#xff0c;吓得我赶紧下掉了项目。但是下掉了项目&#xff0c;就没有办法去排查cpu飙高的原因了&#xff0c;于是又重新上线。 庆幸的是&#…

iPhone14的A16处理器已是地表最强,安卓芯片瑟瑟发抖

苹果发布的A16处理器再次将手机处理器的性能提升至新高度&#xff0c;至此安卓芯片再也没希望赶上苹果&#xff0c;性能方面太弱鸡&#xff0c;安卓手机却在价格方面直追苹果&#xff0c;难怪消费者都不买安卓旗舰手机。 据悉A16处理器的性能比A15提升15%左右&#xff0c;而此前…

android 手机超频降频秘籍

不用软件超频降频CPU GPU 官方正式版没试过&#xff0c;因为我已经刷了心灵的集优版了&#xff0c;心灵的内核已经支持频率调节CPU&#xff0c;但是GPU还没有实现。 CPU篇 CPU频率&#xff0c;governor都在这个文件夹下面&#xff0c;/sys/devices/system/cpu/&#xff0c…

【Unity项目】Unity实现 双屏显示效果

需求&#xff1a;两个屏显示项目&#xff0c;一个屏显示列表&#xff0c;一个屏显示列表按钮点击后的效果。 最近在修改一个项目&#xff0c;是要求分屏显示项目&#xff0c;一个一体机&#xff0c;一个大屏&#xff0c;一体机当作目录界面&#xff0c;大屏当作模型显示界面&am…