IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> IOS性能优化之内存管理与内存爆增(一) -> 正文阅读

[游戏开发]IOS性能优化之内存管理与内存爆增(一)

????????在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性能优化实战>>*********

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:25:48  更:2022-03-21 21:28:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 18:54:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码