为什么iOS内存使用过多会崩溃,性能会下降?腾讯游戏学院专家Devlin在本文给了解释,如何让手游内存占用更小?从内存消耗iOS实时统计开始。

一、问题

在之前的手游项目中,内存使用过多,都开始崩溃了,所以得做iOS内存统计。内存统计有好几种方法:XCode内存使用统计、UnityInternalProfile内存统计,Mono内存统计等方法。

但是XCode统计需要连手机,UnityInternalProfile的内存统计值与XCode内存统计值差距又太大,崩溃时的内存值跟谁有关系?如何在手机上自己显示内存总量?后面就自己琢磨怎样实现一个适合的内存统计功能。

二、测试研究

研究了下UnityInternalProfile,发现它拿的是mach_base_task_info里的resident_size(物理内存占用)

然后我做了个测试,每几帧分配使用一定大小的内存,然后打印出xcode统计的内存和resident_size。

横坐标是时间,纵坐标是内存。

resident_size值的增长随着内存增长,但增长到一定程度就不怎么变了,当时猜测可能是被压缩了,查资料(MacOS有使用内存压缩技术)和代码,发现iOS还有task_vm_info 这个结构体,里面刚好有compress这项。

然后增加compress这项数值的输出,重新测试!

在内存使用持续增加过程中,当resident_size(物理内存)不再增加时,compress这项线性增长。

三、推论

由图可以看出:实际内存使用 = resident + compress。由此可以认为iOS通过压缩内存来减少内存占用。

并且在测试过程中,发现当实际使用内存达到系统物理内存一半时,系统会不断发送memorywarning的警告,达到60%时就会Q掉App。

四、应用

现在只需要实时拿到task_vm_info里的resident 和 compress 就可以统计App的实际内存的使用量了,对于Unity手机项目来说,需要写Native和C#代码,幸运的是,我已经帮你把代码写好了。

在XCodePostProcess::OnPostProcessBuild()里加入如下代码,会在Unity生成的XCode工程自动插入如下Native代码:

XClass AppRender = new XClass(pathToBuiltProject + "/Classes/UnityAppController+Rendering.mm");
if( AppRender != null)
{
string TCode = "";
TCode += "#include <mach/mach_time.h>\n";
TCode += "#include <mach/mach.h>\n";
TCode += "#include <mach/mach_host.h>\n";
TCode += "#include <mach/task_info.h>\n";
TCode += "#include <mach/task.h>\n";
TCode += "static float GetTotalPhysicsMemory( )\n";
TCode += "{\n";
TCode += " kern_return_t kr;\n";
TCode += " mach_msg_type_number_t info_count = TASK_VM_INFO_COUNT;\n";
TCode += " task_vm_info_data_t vm_info;\n";
TCode += " kr = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vm_info, &info_count);\n";
TCode += " if (kr == KERN_SUCCESS) return (float)(vm_info.compressed + vm_info.resident_size) / 1024.0 / 1024.0;\n";
TCode += " return 0;\n";
TCode += "}\n";
TCode += "extern \"C\" float _Get_Profiler_TotalPhysicMemory(){return _fLockStepPhysicMemory;}\n";
TCode += "extern \"C\" void UnityRepaint()";

AppRender.Replace("extern \"C\" void UnityRepaint()",TCode );
}
(左右滑动可查看全部代码)

在UnityC#里加入以下托管代码,调用 Get_Profiler_TotalPhysicMemory()即可实时拿到内存使用值。

#if ( UNITY_IPHONE && !UNITY_EDITOR )

[DllImport("__Internal")]
static extern float _Get_Profiler_TotalPhysicMemory( );

public static float Get_Profiler_TotalPhysicMemory( )
{
return _Get_Profiler_TotalPhysicMemory( );
}
#endif
(左右滑动可查看全部代码)

五、补充

由于系统有分页机制,即你申请使用1字节的内存,系统也有可能会给你一整页(16k大小的物理页),所以会导致这里的实际内存使用量(内存分页总和)与XCode内存统计(精确统计)不完成相等,但大致符合一定比例。

如何让手游内存占用更小?从内存消耗iOS实时统计开始的更多相关文章

  1. linux服务器内存占用太高-释放内存

    修改/proc/sys/vm/drop_caches,释放Slab占用的cache内存空间(参考drop_caches的官方文档): Writing to this will cause the ke ...

  2. DNF手游公测或将只有安卓版 iOS系统怎么办?

    DNF手游在8月10号确定延期后,目前还不知道新的上线时间.玩家都很关心DNF手游新的公测时间,DNF手游官网的预约数据也是不断突破新高,最终突破了五千万!我们目前拿到的小道消息,DNF手游会在9月1 ...

  3. python垃圾回收,判断内存占用,手动回收内存,二

    以下为例子,判断计算机内存并释放程序内存. # coding=utf8 import time import psutil, gc, commands,os from logger_until imp ...

  4. 绘制FastMM内存分配流程图(小块内存分配)

    http://blog.csdn.net/henreash/article/details/38751353

  5. 知物由学|游戏开发者如何从容应对Unity手游风险?

    本文由  网易云发布. "知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不 ...

  6. 年度游戏圈2018白皮书解析手游折扣app哪个好及靠谱程度分析

    2018年,随着全国暂停游戏版本的审核和发布<综合防控儿童青少年近视实施方案>(控制新的在线游戏数量),游戏行业受到的影响不小. 在游戏产业中,游戏行业2018年的收入同比增长5.2%,远 ...

  7. 《疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)》

    <疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)> 基本信息 作者: 李刚    肖文吉 出版社:电子工业出版社 ISBN:9787121224379 ...

  8. Code Helper占用大量CPU和内存

    项目架构: React+TS+DVA 设备及软件: 设备:Mac 软件:VSCode 场景: 在Mac中使用VSCode运行时发现项目编译非常卡顿,时间长达五六分钟以上,并且项目启动后访问页面,页面也 ...

  9. 『Spring Boot 2.4新特性』减少95%内存占用

    节省 95%的内存占用,减少 80%的启动耗时. GraalVM 是一种高性能的虚拟机,它可以显著的提高程序的性能和运行效率,非常适合微服务.最近比较火的 Java 框架 Quarkus 默认支持 G ...

随机推荐

  1. BigDecimal类用于计算(不会丢失精度)

  2. Ubuntu16.04深度学习基本环境搭建,tensorflow , keras , pytorch , cuda

    Ubuntu16.04深度学习基本环境搭建,tensorflow , keras , pytorch , cuda Ubuntu16.04安装 参考https://blog.csdn.net/flyy ...

  3. ubuntu 12.04 配置vsftpd 服务,添加虚拟用户,ssl加密

    1.对于12.04的vsftpd 有一些bug,推荐安装版本vsftpd_2.3.5-1ubuntu2ppa1_amd64.debapt-get install python-software-pro ...

  4. #define 和 const

    来自:牛客网参考解析 1.const定义常量是有数据类型的,而#define宏定义常量却没有2.const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,   而对后者只 ...

  5. ZCGL大数据平台性能优化

    对HBase数据库建索引 参见:基于Phoenix对HBase建索引   https://www.cnblogs.com/ratels/p/11203313.html 将HBase访问微服务整合到模块 ...

  6. 不一样的Vue实战3:布局与组件

    不一样的Vue实战3:布局与组件  发表于 2017-06-05 |  分类于 web前端|  |  阅读次数 11534 http://yangyi1024.com/2017/06/05/%E4%B ...

  7. 仿照Android标准API写的各种形式的弹出框

    strings.xml: <?xml version="1.0" encoding="utf-8"?> <resources> < ...

  8. Mybatis入门(六)联查之多对一

    Mysql可以联查,但Mybatis也可以联查只是没有MySQL联查的舒服需要配置很多文件. 开始搭建环境: MySQL新建两个表一个Student一个Teacher表: Teacher表: CREA ...

  9. 题解 zr1212 【20WC集训】货币

    题目链接 我们给每个连通块图上一种颜色.不同的连通块涂不同的颜色. 首先,我们定义\(f_r\)表示:使\([l,r]\)包括\([1,r]\)里所有颜色的最大的\(l\). 然后我维护一个变量\(p ...

  10. Zabbix WebUI 配置监控Zabbix Agent

    Zabbix WebUI 配置监控Zabbix Agent 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.部署zabbix服务 1>.部署zabbix server 和z ...