关于@autoreleasepool的性能测试及手动释放自动释放池

2024-01-24 16:38

本文主要是介绍关于@autoreleasepool的性能测试及手动释放自动释放池,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://yangchao0033.github.io/blog/2015/12/31/guan-yu-at-autoreleasepoolde-ce-shi-ji-shi-yong/

首先,我们先对使用autoreleasepool的场景进行性能对比。

  • 不用autoreleasepool
- (void)doSomething {NSMutableArray *collection = @[].mutableCopy;for (int i = 0; i < 10e6; ++i) {NSString *str = [NSString stringWithFormat:@"hi + %d", i];[collection addObject:str];}NSLog(@"finished!");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8


不使用性能如下如所示: 
不使用

  • 使用autoreleasepool
- (void)doSomething {NSMutableArray *collection = @[].mutableCopy;for (int i = 0; i < 10e6; ++i) {@autoreleasepool {NSString *str = [NSString stringWithFormat:@"hi + %d", i];[collection addObject:str];}}NSLog(@"finished!");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

使用效果如下图所示: 
使用autoreleasepool

综上,当需要在程序中创建大量的临时变量时(大量也可指数量多,不确定,比如从数据库中读取数据时),很容易使内存产生峰值又回到内存低谷,这样对程序的性能会产生很大影响,而使用自动释放池后,峰值明显有所下降。 
原因:由于在mian函数中已经为我们添加了自动释放池,如下所示: 

#import <UIKit/UIKit.h>
#import "AppDelegate.h"int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

而当autoreleasepool的右括号结束后,会对整个autoreleasepool做一次倾倒。但是这会使其中局部产生的大量零时变量无法及时释放,直到for循环结束后抵达main中autoreleasepool的右括号位置才能释放。这样会在局部位置发生内存峰值。 
官方提出的解决方案是,在大量产生局部变量的位置用autoreleasepool代码块进行包装。比如for循环中要执行的语句,这样每次for循环结束后就会及时收回临时变量占用的内存空间。 

思考:如何在指定的次数时,及时释放自动释放池中的临时变量

使用mrc下的特性
在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译
如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可
  • 1
  • 2
  • 3

这里的需求我们可以使用MRC时代的一个重量级的自动释放池,通常用来创建偶尔需要释放清空的池。

- (void)doSomething {int count = 0;NSMutableArray *collection = @[].mutableCopy;NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];for (int i = 0; i < 10e6; ++i) {NSString *str = [NSString stringWithFormat:@"hi + %d", i];[collection addObject:str];if (++count == 100) {/** 每一百次倾倒一次池子 */[pool drain];count = 0;}}/** 用来倾倒当i的个数不是100的倍数时,比如读取数据库数据时,数据总数为不确定值 */[pool drain];NSLog(@"finished!");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这篇关于关于@autoreleasepool的性能测试及手动释放自动释放池的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640310

相关文章

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

Java慢查询排查与性能调优完整实战指南

《Java慢查询排查与性能调优完整实战指南》Java调优是一个广泛的话题,它涵盖了代码优化、内存管理、并发处理等多个方面,:本文主要介绍Java慢查询排查与性能调优的相关资料,文中通过代码介绍的非... 目录1. 事故全景:从告警到定位1.1 事故时间线1.2 关键指标异常1.3 排查工具链2. 深度剖析:

深入解析Java NIO在高并发场景下的性能优化实践指南

《深入解析JavaNIO在高并发场景下的性能优化实践指南》随着互联网业务不断演进,对高并发、低延时网络服务的需求日益增长,本文将深入解析JavaNIO在高并发场景下的性能优化方法,希望对大家有所帮助... 目录简介一、技术背景与应用场景二、核心原理深入分析2.1 Selector多路复用2.2 Buffer

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我