开发者专栏

关注:2180

当前位置:足球投注 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 1743|回复: 27
发新帖

[士郎] Unity移动平台内存限制相关详解

[复制链接]  [移动端链接]
排名
3
昨日变化

足球投注 www.zjrxh.com 6275

主题

6789

帖子

2万

积分

Rank: 16

UID
1231
好友
185
蛮牛币
2116
威望
30
注册时间
2013-7-29
在线时间
3208 小时
最后登录
2018-4-27

社区QQ达人活力之星原创精华达人突出贡献奖财富之证游戏蛮牛QQ群会员蛮牛妹VIP

跳转到指定楼层
楼主
发表于 2018-3-13 12:22:33 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
PSS在不同手机测试的结果是不同的


USS = 进程独占的内存
RSS = USS + 共享内存
PSS = USS + 共享内存/共享这段内存的进程数量


所以,由于加上了共享内存,PSS的数值是非常不稳定的,和手机的系统和版本都有关系。由于共享内存还需要除以进程数,它甚至还和你安装的软件,和运行时后台程序的数量相关……


因此,你家随便一台手机测试出来的PSS,和腾讯检测时测出来的PSS很可能不同,也就不能死板地拿腾讯的标准对比。
正确的做法是,准备一个固定的测试环境,然后提交一个版本到腾讯,得出两者PSS的差值。然后以后的本地测试都减去这个固定差值就行。
或者,用腾讯本家的游戏作为对比参考,比它们低就行。


腾讯的可以,凭啥你的就不行呢?

用PSS判断应用的内存占用科学吗?
当一个进程被杀掉后,释放出来的内存量是USS。
应用本身主动申请的所有内存,堆/栈/纹理数据等等都属于private dirty,也就是USS。共享内存并不是公共库这样的概念,你使用公共库,在公共库的范围创建了新的对象,那部分对象依然属于USS。
共享内存在内存分配上有点类似“静态数据”或者“代码”,应用对它只能读取而不能写入。想要写入就必须先复制一份到USS。所以按我们常规的对“内存分配”的理解,USS就是单个进程占用的内存的全部。
所以,用USS来判断一个应用的内存占用才是科学的。我认为,PSS多出来的“share dirty / progress number”部分根本毫无意义。

PSS看起来这么不科学,为啥要把它当作限制?

  • 安卓的任务管理器显示的应用内存占用就是PSS。并不确定系统是否是以它作为管理基准。
  • USS在非Root的情况下,不能由外部进程获得。有可能是当初为了检测方便。
  • 很多事情并没有什么“为什么”,你只能接受。而且在孤立环境下PSS检测确实问题不大,因为同一引擎同一时期开发的游戏,PSS比USS多出来的部分“大概”是个固定值,标准相应加上这个固定值就好了。


如何获取PSS和USS?
虽然控制内存的时候大部分情况用Unity自己的Profiler就行了——


但Unity确实不会统计所有的内存占用。我们可以确定,所有额外引入的C代码库它们自己申请的非托管内存都不会计算在内,其中就包括lua。另外,平台渠道的架包它们自己申请的内存也不会计算在内。


如果只是自己控制内存的话,只看Unity的Profiler和Lua单独的内存统计差不多就够了。但是像渠道代码,语音库这类东西,虽然我们对它们无能为力,毕竟是捆绑在一起的,必须给它们挪出相应内存的空闲来,所以我们依然必须关心整个应用的内存占用(但Unity Profiler的结果同样要关心,因为它才是普适的)
而比起用adb查看,能够通过游戏界面呈现出来显然更加便利。


应用内部获得内存数据的办法是 Debug.getMemoryInfo。
[AppleScript] 纯文本查看 复制代码
Debug.MemoryInfo localMemoryInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(localMemoryInfo);
localMemoryInfo.getTotalPss();
localMemoryInfo.getTotalPrivateDirty();//USS


不编程的话,可以用adb工具查看
adb shell dumpsys meminfo 进程名
(注意结果里privte dirty就是USS)

获取的实时PSS/USS可以用来做什么?
主要是Debug时用来参考??悸堑皆诵行?,发布版本最好关闭这个功能。


但……它也可以帮助大家确保通过平台PSS上限的检测。与其担心偶尔超过规定的PSS上限而畏手畏脚降低资源数量,不如放开手,然后在即将到达PSS上限的时候强行回收内存。实在不够的时候,甚至可以禁止新资源加载,用空白物体取代,只保证游戏逻辑可以持续下去。


虽然这里只是为了应付检测,但在实际游戏运行中,如果确实出现了内存不足的情况,这种“放弃游戏体验”的做法也不失为一个办法,毕竟总比应用崩掉要好。

如何才能避免我们的应用由于内存不足崩掉?
获取PSS/USS的数值并不能帮助我们做到这点。

——因为操作系统并不会因为一个进程占用了固定数量的内存而杀掉它(更不要说每个设备的内存总量还不一样),操作系统只会在内存严重不足,也没有后台进程可杀的时候,才会为了保证系统安全而杀掉前台进程。


所以,我们要做的就是在内存确实不够的时候设法降低内存占用,乃至牺牲体验。具体的做法就是:
  • 执行GC
  • 回收资源,删除缓存,删除预加载内容
  • 降低画质级别
  • 以上皆无效,拒绝新资源的加载
  • 要求用户重启应用


执行时机:

一个办法是实时获取当前系统剩余内存并处理


某著名游戏的代码


MemoryInfo:

availMem 当前系统剩余内存
threshold “低内存”的标准
lowMemory 当availMem<threshold即为true,这时候系统会开始关闭后台应用

这段逻辑也可以用来验证回收资源的成果,判断是否要使用更激进的做法。

接受系统发出的内存警告提示

安卓:

onTrimMemory(int state)
当进程在前台时,state的值可能是以下三个
TRIM_MEMORY_RUNNING_CRITICAL:内存不足(后台进程不足3个)
TRIM_MEMORY_RUNNING_LOW:内存不足(后台进程不足5个)
TRIM_MEMORY_RUNNING_MODERATE:内存不足(后台进程超过5个)
这个事件触发比较早,操作系统还可以关闭后台进程来周转。只是提醒在用户内存的紧迫程度。

onLowMemory()
在所有后台进程关闭后,同时处于lowMemory状态时触发。这时候系统已没有内存腾挪的空间。剩余内存继续变少,前台应用随时可能被关闭,以保障操作系统的正常运行(否则只能死机)

IOS:
[AppleScript] 纯文本查看 复制代码
- (void)didReceiveMemoryWarning
{
(int)OSMemoryNotificationCurrentLevel());
}

OSMemoryNotificationCurrentLevel()的枚举:[/size][/font][/indent][indent][font=微软雅黑][size=3]
OSMemoryNotificationLevelAny = -1 正常
OSMemoryNotificationLevelNormal = 0 正常
OSMemoryNotificationLevelWarning = 1 内存不足警告
OSMemoryNotificationLevelUrgent = 2 严重内存不足警告
OSMemoryNotificationLevelCritical = 3 闪退(所以实际上无法收到此消息)


OSMemoryNotificationLevelWarning可以认为等效onTrimMemory(TRIM_MEMORY_RUNNING_CRITICAL),只是提示出现内存不足的现象,这时候会通过关闭后台进程来获取额外内存,并不一定非要处理。
OSMemoryNotificationLevelUrgent 可以认为等效onLowMemory,表示系统已经处于非常危险的状态,前台进程随时都可能被关闭。

在Unity 5.6之后,提供了系统事件Application.lowMemory,相当于:

- iOS: [UIApplicationDelegate applicationDidReceiveMemoryWarning]
- : onLowMemory() and onTrimMemory(level == TRIM_MEMORY_RUNNING_CRITICAL)

并不应该无脑的执行回收逻辑
当内存出现警告时,并不代表必须要马上执行缩减内存的操作,因为这些操作都是有代价的,仅仅是频繁地GC就会导致游戏体验的极大下降,而这是有可能在不闪退的前提下避免的。


系统给出的内存不足提示本身是为App准备的,如果你在浏览网页过程中弹出了支付宝,显然,你并不希望在支付宝运行过程中把网页的进程杀掉。当内存不足,网页进程要被杀掉前,系统就会给支付宝发一个提示,希望它也能停止申请内存,以便给网页进程?;?。


从App的角度,每个应用都应该尽可能共存,内存警告系统也是这样设计的。但是游戏则不同。对于玩家而言,进入游戏把后台的网页杀掉不仅没有关系,也是预期会发生的事。毕竟现在也不兴玩游戏前“清除内存加速球”之类的玩意儿了。


我进游戏前开了几个应用,我没有强关他们,然后我进游戏,游戏为了不杀掉他们却要强行缩减自己的内存降低画质让游戏变卡??

这不是自找没趣么?

不过,从实际结果来看,当到了OSMemoryNotificationLevelWarning,onTrimMemory(level == TRIM_MEMORY_RUNNING_CRITICAL),也就是Unity的Application.lowMemory的触发点的时候,应用确实已经处于较为危险的地步。虽然游戏还可以正常运行,后台进程大多已经关闭,切回桌面也需要重新启动,甚至来个电话收个短信都可能导致游戏被关闭。虽然可能不至于闪退,体验已经变得不好。

个人建议,这个提示出现后只进行对体验影响较小的处理。

如果连续出现,则加大处理的力度。

但如果连onLowMemory,OSMemoryNotificationLevelUrgent都已经被触发了,则必须不计一切代价将内存降低下去,不处理是真的要完蛋的。


此外,onLowMemory,OSMemoryNotificationLevelUrgent在内存申请较快的情况是可能不出现便直接闪退的,它们并不保险。这点在场景加载过程极易发生,所以在加载过程时对内存警告的处理就要更加保守。而在内存较为平稳的阶段,就可以稍微倦怠一些,等待onLowMemory出现后再处理。



然而这些做法其实无异于在刀尖上跳舞,可以的话,还是要尽力将内存降低下去,应用切换的体验也是有必要保证的。切出游戏便无法回来,玩家的体验并不好。



然而如果有平台的PSS限制的话……因为他们的限制往往过于求稳,出现Application.lowMemory(甚至在之前)恐怕就必须清理内存才能满足他们的要求,也就不用考虑那么多了。

知乎@flashyiyi









跟我念“站长妹纸萌萌哒!”我说站长,你说YO!爱你们么么哒~
6蛮牛粉丝
1095/1500
排名
4108
昨日变化
5

5

主题

503

帖子

1095

积分

Rank: 6Rank: 6Rank: 6

UID
239879
好友
1
蛮牛币
1856
威望
0
注册时间
2017-8-26
在线时间
279 小时
最后登录
2018-4-24
沙发
发表于 2018-3-13 14:11:25 | 只看该作者

排名
1119
昨日变化
1

13

主题

981

帖子

2637

积分

Rank: 9Rank: 9Rank: 9

UID
68430
好友
7
蛮牛币
9372
威望
0
注册时间
2015-1-14
在线时间
703 小时
最后登录
2018-4-28
板凳
发表于 2018-3-13 17:54:00 | 只看该作者
66666666666

5熟悉之中
715/1000
排名
6107
昨日变化
37

0

主题

382

帖子

715

积分

Rank: 5Rank: 5

UID
146677
好友
9
蛮牛币
2491
威望
0
注册时间
2016-4-25
在线时间
143 小时
最后登录
2018-4-27
QQ
地板
发表于 2018-3-13 20:17:52 | 只看该作者
支持一下,谢谢分享

7日久生情
2467/5000
排名
3388
昨日变化
14

0

主题

1764

帖子

2467

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219676
好友
0
蛮牛币
2310
威望
0
注册时间
2017-7-12
在线时间
323 小时
最后登录
2018-4-28

活力之星

5#
发表于 2018-3-13 20:57:42 | 只看该作者
谢谢分享
[发帖际遇]: 夜雨微凉 在网吧通宵,花了 1 蛮牛币. 幸运榜 / 衰神榜

3偶尔光临
203/300
排名
10490
昨日变化
2

1

主题

74

帖子

203

积分

Rank: 3Rank: 3Rank: 3

UID
27144
好友
0
蛮牛币
895
威望
0
注册时间
2014-5-29
在线时间
44 小时
最后登录
2018-3-13

VIP

6#
发表于 2018-3-13 22:23:48 | 只看该作者

7日久生情
4001/5000
排名
136
昨日变化

18

主题

308

帖子

4001

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
67323
好友
1
蛮牛币
2871
威望
0
注册时间
2015-1-10
在线时间
1595 小时
最后登录
2018-4-27
7#
发表于 2018-3-14 01:24:26 | 只看该作者
这就是一直寻找的干货

4四处流浪
343/500
排名
9358
昨日变化
125

0

主题

135

帖子

343

积分

Rank: 4

UID
99709
好友
0
蛮牛币
216
威望
0
注册时间
2015-5-12
在线时间
106 小时
最后登录
2018-4-28
8#
发表于 2018-3-14 08:46:56 | 只看该作者
感谢分享

7日久生情
1692/5000
排名
3665
昨日变化
20

0

主题

1151

帖子

1692

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
185339
好友
0
蛮牛币
2369
威望
0
注册时间
2016-11-20
在线时间
195 小时
最后登录
2018-4-27
9#
发表于 2018-3-14 09:20:48 | 只看该作者
已收藏,谢谢分享

6蛮牛粉丝
1009/1500
排名
2769
昨日变化
14

0

主题

217

帖子

1009

积分

Rank: 6Rank: 6Rank: 6

UID
168312
好友
0
蛮牛币
1763
威望
0
注册时间
2016-9-13
在线时间
340 小时
最后登录
2018-4-27
10#
发表于 2018-3-14 09:32:07 | 只看该作者
学习了,谢谢分享
[发帖际遇]: 1169895688 发帖时在路边捡到 1 蛮牛币,偷偷放进了口袋. 幸运榜 / 衰神榜

6蛮牛粉丝
1227/1500
排名
2858
昨日变化
4

0

主题

458

帖子

1227

积分

Rank: 6Rank: 6Rank: 6

UID
220310
好友
1
蛮牛币
2115
威望
0
注册时间
2017-5-2
在线时间
327 小时
最后登录
2018-4-28
11#
发表于 2018-3-14 09:32:09 | 只看该作者

5熟悉之中
504/1000
排名
6699
昨日变化
4

3

主题

214

帖子

504

积分

Rank: 5Rank: 5

UID
209710
好友
0
蛮牛币
1409
威望
0
注册时间
2017-6-15
在线时间
123 小时
最后登录
2018-4-26
12#
发表于 2018-3-14 09:34:59 | 只看该作者
多谢分享,学习一下

7日久生情
1725/5000
排名
2320
昨日变化
2

8

主题

722

帖子

1725

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
83438
好友
2
蛮牛币
1926
威望
0
注册时间
2015-3-23
在线时间
457 小时
最后登录
2018-4-18
13#
发表于 2018-3-14 09:48:01 | 只看该作者
收藏 厉害

4四处流浪
367/500
排名
12136
昨日变化
4

3

主题

132

帖子

367

积分

Rank: 4

UID
216830
好友
2
蛮牛币
236
威望
0
注册时间
2017-4-9
在线时间
169 小时
最后登录
2018-4-25
14#
发表于 2018-3-14 09:50:15 | 只看该作者

4四处流浪
314/500
排名
7265
昨日变化
6

0

主题

106

帖子

314

积分

Rank: 4

UID
248343
好友
0
蛮牛币
583
威望
0
注册时间
2017-10-12
在线时间
58 小时
最后登录
2018-4-21
15#
发表于 2018-3-14 09:57:02 | 只看该作者
v5v5v5v5v5v5v5

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 足球投注 返回列表
幸运农场开奖结果查询 | 508| 464| 431| 285| 891| 827| 969| 117| 804| 961|