Unity内存存储揭秘
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
内存优化是一个老生常谈问题了,本篇博客把一些关于内存的知识点做了一个总结,给读者介绍一下,我们查看游戏运行内存问题,通常的做的法是借助一些Unity的第三方工具,但是作为程序来说还是先要明白其导致内存的问题所在,才能对症下药,先看通过Profiler显示的内存:
Used Total和Reserved 均是物理内存,其中Reserved是unity向系统申请的总内存,Unity底层为了不经常向系统申请开辟内存,开启了较大一块内存作为缓存,即所谓的Reserved内存,而运行时,unity所使用的内存首先是向Reserved中来申请内存,当不使用时也是先向Reserved中释放内存,从而来保证游戏运行的流畅性。
一般来说,我们均建议尽可能地控制Used Total的大小,Used Total越大,则Reserved Total越大,而当Used Total降下去后,Reserved Total也是会随之下降的(但并不一定与Used Total同步)。
通过PSS来查看移动端的内存是相当不准确的。Profiler记录的是通过引擎分配的真实物理内存,而PSS中多出的内存大致分为两部分,一部分是App在运行会调用底层的一些核心库,这些库都会占用一定的内存;第二部分则是移动系统决定的,即虽然游戏中已经将资源卸载掉,但在系统层面上,系统并不会及时将其清除,而是将其缓存住,这样做的处理是为了便于以后该资源的复用效率,同时,当系统的内存分配达到上限时,系统本身会调用内存清理机制来轮询这些缓存区域,进而释放内存。
ManagedHeap的内存值是由所写的C#代码来引起并造成的,建议时刻关注CPU Profiler中的GC Collcet值,查看由哪些选项分配较大或不断分配GC Allocation。这个是造成ManagedHeap不断增大的原因。
GfxDriver可以理解为GPU显存开销,主要由Texture,Vertex buffer以及index buffer组成。所以尽可能地减少或释放Texture和mesh等资源,即可降低GfxDriver内存。
ManagedHeap的大小与你的GameObject数量、资源量无关,仅是你的代码造成的。如果是在Editor中运行时,那么该数值是会比较大,因为编
辑器运行游戏时,底层会做很多额外的事情,比如更多的log输出等,从而占据较多的堆内存。而如果在真机运行时看到该数值时,那么80M是比较大
的,这个需要你对你的代码来进行优化,避免一些不必要的堆内存分配。比如,不要总是new一个class、array、container等等。你可以在CPU Profiler
中的GC Alloc处查看游戏每帧的堆内存分配。同时,Managedheap的大小完全是有Mono来决定的,用户所写的任何脚本均是由Mono来负责解析。
同时,Mono的堆内存是只升不降的,这是Mono的一个问题,Unity暂时也无法对其进行修改。因此,只能建议开发者在编写代码时尽可能地优化嗲吗,
避免不要的堆内存分配。
另外,Mono内存和native内存是PSS内存主要的组成部分,mono内存更多的起到内存调用的功能,因此常常成为了开发人员优化内存的起点;
而native内存中包含了大量对象的资源,也是内存优化中的重要部分。
再以NGUI或者说UGUI为例如何去做优化:
通常一个Panel会产生1个或多个Draw Call,以一个Panel为单位,Draw Call 的数量通常由当前 Panel 中
使用的Atlas、Font的数量所决定。
要降低UI渲染时的 Draw Call数量则需要对 Atlas 的制作进行合理的规划,即在保证使用较少的 Atlas 的同时,
还需要保证 Atlas之间不会存在交叉遮挡。
要注意UI Texture的使用,每个UITexture自身会占用一个Draw Call,同时如果其Depth值穿插在了其他来自相
同Atlas的UISprite中,还会导致Draw Call的打断,造成不必要的额外Draw Call。
另外还可以借助Panel Tool和Draw Call Tool来对UI部分的Draw Call进行分析,前者可以显示每个UIPanel包含
了多少个Draw Call,而后者可以显示每个Draw Call由哪些UIWidget组成。"
其实我们只要抓住主要矛盾就可以解决问题,内存优化需要具体问题具体分析,Unity程序主要分为三部分:
以上三部分在前面给读者介绍过,这里只是列举了一下,将Unity打包后可以看到这三部分内容。
Unity内存存储揭秘的更多相关文章
- Unity内存理解(转)
Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBundle,其实两者区别不大. Resources.Load就是从一个缺省打进程序包里的AssetBu ...
- unity内存管理(转)
转自:https://www.cnblogs.com/zsb517/p/5724908.html Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBun ...
- Redis内存存储结构分析
1 Redis 内存存储结构 本文是基于 Redis-v2.2.4 版本进行分析. 1.1 Redis 内存存储总体结构 Redis 是支持多key-value数据库(表)的,并用 RedisDb 来 ...
- C/C++内存存储
#include <stdio.h> #include "string.h" #include "malloc.h" void Swap(int a ...
- memcached全面剖析–2. 理解memcached的内存存储
Slab Allocation机制:整理内存以便重复使用 最近的memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存. 在该机制出现以前,内存的分配是通过对所有记录简 ...
- C/C++内存存储问题
#include <stdio.h> #include "string.h" #include "malloc.h" void Swap(int a ...
- 1.C#基础学习笔记3---C#字符串(转义符和内存存储无关)
技术qq交流群:JavaDream:251572072 教程下载,在线交流:创梦IT社区:www.credream.com ------------------------------------- ...
- 【解惑】剖析float型的内存存储和精度丢失问题
问题提出:12.0f-11.9f=0.10000038,"减不尽"为什么? 现在我们就详细剖析一下浮点型运算为什么会造成精度丢失? 1.小数的二进制表示问题 首先我们要搞清楚下面两 ...
- Go Web:数据存储(1)——内存存储
数据可以存储在内存中.文件中.按二进制序列化存储的文件中.数据库中等. 1.内存存储 2.CSV文件存储 3.gob序列化存储 内存存储 将数据存储到内存中.此处所指的内存是指应用程序自身的内存空间( ...
随机推荐
- 20145329 吉东云《Java程序设计》第二周学习总结
教材学习内容总结 第三章 基础语法 基本类型 1.整数(short.int.long) 2.字节(byte),可表示-128~127的整数 3.浮点数(float/double),主要储存小数数值 4 ...
- linux块设备读写流程
在学习块设备原理的时候,我最关系块设备的数据流程,从应用程序调用Read或者Write开始,数据在内核中到底是如何流通.处理的呢?然后又如何抵达具体的物理设备的呢?下面对一个带Cache功能的块设备数 ...
- oracle添加用户并给予管理员身份登陆
sqlplus / as sysdba;--超级管理员sys登陆 show user;--显示当前用户 conn system/admin;--切换用户 CREATE user admin ident ...
- "ImportError: cannot import name OVSLegacyKernelSwitch"
My VirtualMachine OS is Ubuntu14.04, Linux. Recently I want to install the mininet in my OS, and I u ...
- jQuery获取属性值的方法
1.利用绑定事件: $(".callback").on("click","#knbh",function(){ ***** ...
- Springcloud/Springboot项目绑定域名,使用Nginx配置Https
https://blog.csdn.net/a_squirrel/article/details/79729690 一.Https 简介(百度百科) HTTPS(全称:Hyper Text Trans ...
- placehold.it-在线图片生成器
placehold的介绍 当我们进行网页设计时,经常会使用各种尺寸的图片.有时候我们用一个固定宽和高的div来进行代替,可是这样的效果不是很明显,而且还要进行各种各样的文字说明:或者我们得从网上寻找各 ...
- activity之间通过全局变量传递数据
activity之间通过全局变量传递数据 一.简介 Application域中的onCreate方法是Android程序的入口,Android程序运行的时候就自动加载Application的对象,感觉 ...
- HDU 1693 插头dp入门详解
放题目链接 https://vjudge.net/problem/22021/origin 给出一个n*m的01矩阵,1可走0不可通过,要求走过的路可以形成一个环且可以有多个环出现,问有多少不同的 ...
- 020——VUE中变异方法push的留言版实例讲解
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...