1)Android 10 零碎下的 PSS 数值统计不准
2)Memory Profiler 中的类型内存大小计算
3)Addressable 加载 Bytes 文件在手机上报错
4)应用 SBP 打 Bundle,如何读取 AssetBundleManifest
5)GameObject 如何开释从 Bundle 中加载的 Asset
这是第 215 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。
UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)
Memory
Q:从下图测试的后果来看,Android 10.0 的 PSS 的内存值是平的,没有任何变动。但如果用 Android 9.0 版本的测试机测试,数值就是失常。初步猜想这个就是 Android 10 的内存反馈,但到底是否为 Bug 还不确定。有遇到雷同状况的小伙伴吗?
A:同样被 Android 10 坑了,来答复一下起因:
ActivityManager 的
public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
变了。
/** <p>As of {@link android.os.Build.VERSION_CODES#Q Android Q}, for regular apps this method * will only return information about the memory info for the processes running as the * caller's uid; no other process memory info is available and will be zero. * Also of {@link android.os.Build.VERSION_CODES#Q Android Q} the sample rate allowed * by this API is significantly limited, if called faster the limit you will receive the * same data as the previous call.</p> */
查了一下安卓源码,这个值竟然默认是 5 分钟,也就是说 5 分钟更新一次,所以看起来是平的。
PS:能够间接用这个命令看到这个值:
$ dumpsys activity settings memory_info_throttle_time=300000
感激 littlesome@UWA 问答社区提供了答复
Memory
Q:在 Unity 2019.3.1f1 的版本中应用 Memory Profiler 应用 Preview 0.2.5 的版本,在进行剖析时,看到 Matrix4x4 构造是值类型,然而大小只占用了 64 字节,即 444 的大小,类型中定义的只读属性在编译后主动生成的 Backingfield 没有占用空间?还是底层实现采取了什么机制?
同样,针对援用类型,大小计算是怎么样一种形式?心愿钻研过 Memory Profiler 源码的大佬帮忙解答下。
A1:初步狐疑这里的只读属性是在 get 办法中间接通过相似实时计算、new 的形式(即办法返回值的形式)实现的(不缓存)——此时在 IL 层面不会生成 Backingfield(不占用内存)。
感激 Wayland@UWA 问答社区提供了答复
A2:你能够反编译一下 Matrix4x4,会发现就像你狐疑的那样都是实时计算的。
其中一个起因就是:例如咱们解决 Instancing 的时候,往往要筹备一个 Matrix4x4[],这种数据结构保障矩阵无效数据是最紧凑的,能够一次性发送给 GPU,做到最优化。
感激黄程 @UWA 问答社区提供了答复
Addressable
Q:利用 Assdressable 加载二进制文件,手机上报错。编辑器下这样加载 var loadOp = Addressables.LoadAssetAsync(tablePath);然而打包后手机上报错:
[SYS_ERROR]: Exception encountered in operation Resource(table_c#_assets_all_1f4a006d39ea75ca48efd21a455601c1.bundle): RemoteAssetBundleProvider unable to load from url jar:file:///data/app/com.funplus.kingsgroup.wod-zHxfbteVjnHJeanZLbCPog==/base.apk!/assets/aa/Android/Android/table_c, result=‘HTTP/1.1 404 Not Found’.
UnityEngine.AsyncOperation:InvokeCompletionEvent()
A:先解压看一下 APK 里,确定 Table_c 这个 Bundle 是否真的打进去了。
补充:
Bundle 名:
table_c#_assets_all_1f4a006d39ea75ca48efd21a455601c1.bundle
URL 名:
jar:file:///data/app/com.funplus.kingsgroup.wod-zHxfbteVjnHJeanZLbCPog==/base.apk!/assets/aa/Android/Android/table_c
看上去是 #被截断了,应该是 URL 规定中不容许应用这个符号,把 Bundle 改个名字吧。
感激黄程 @UWA 问答社区提供了答复
AssetBundle
Q:降级到 Unity 2019 之后,应用 BuildPipeline.BuildAssetBundles 办法打 Bundle 变得很慢。咱们发现 Unity 新推出的 Scriptable Build Pipeline 有更快的打包速度(1 个小时降为 15 分钟),然而作为兼容之前 AssetbundleManifest 的新类型 CompatibilityAssetbundleManifest 并没有被打成 Bundle,而是一个 Yaml 格局的文件:
想求教一下在用 Scriptable Build Pipeline 的搭档,这里是如何解决的?或者说资源的依赖关系是如何存储的。
PS:没用 Addressable,因为是线上运行我的项目,资源的门路都配在了 Excel 里,须要改的中央太多。
A:应用 AssetDatabase.CreateAsset 保留 CompatibilityAssetBundleManifest,再独自打着一个 Bundle。
感激张斌 @UWA 问答社区提供了答复
AssetBundle
Q:从 Bundle 中加载的资源,如果是 Texture、Material 之类,用 Resources.UnloadAsset() 就能间接把它从内存中开释。
如果是 GameObject,不能对它调用 Resources.UnloadAsset。目前的做法是,只执行了 Destroy,等到内存上涨到肯定水平,调用 Resources.UnloadUnusedAssets(),来开释它们。
总感觉很亏,请问有没有方法,能够像凑合 Texture 那样,间接开释 GameObject?
A1:个别不必被动开释。
Bundle 外面一加载是一家子的,比方加载 GameObject,会主动带上援用的材质,援用的材质又会主动带上援用的贴图和 Shader 等等。
要洁净地开释,你要让这一家子都整整齐齐的,十分麻烦。倡议是间接用 Bundle.Unload(true) 实现残缺开释。
感激欧月松 @UWA 问答社区提供了答复
A2:DestroyImmediate(object,true);
感激谢谢 @UWA 问答社区提供了答复
A3:测试了一下 DestroyImmediate(object,true),发现它并不开释援用的材质和贴图,哪怕这个材质和贴图仅仅被该 GameObject 一个人调用,不过感觉还是须要调用这个函数,开释一点总比什么都不开释要好。
感激题主李宏亮 @UWA 问答社区提供了答复
*
明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)