问答 Instruments 如何看 Mono 内存分配

侑虎科技 · 2020年09月07日 · 1270 次阅读

1)Instruments 如何看 Mono 内存分配
​2)关于 Addressable v1.11.2 的疑问
3)展开 UV2 时导致 Mesh 顶点数增加
4)提升 Unity 编辑器中代码的编译速度
5)Renderdoc 调试的疑问

这是第 217 篇 UWA 技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间 10 分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)


Memory

Q:例如在分配了一个 10MB 数组,对应在 Unity Profiler 中会看到开辟了至少 10MB 大小的 Mono 内存。

那么在 Instruments 中,如何查看分配的内存信息呢?Allocations 中的信息是此进程中分配的所有内存信息吗,尝试分配过 100MB 内存,Allocations 中的统计没有任何增长。

A:我这边也做了测试:

创建了 100MB 大小的 int 数组,Size 实际应该是 400MB。
然后到 Profile 观察:


可以看到 ManagedHeap 正确分配了这 400MB 的空间。
然后打包 iOS 后到 Xcode 运行,运行前首先把 Run 这个 Scheme 的 Malloc Stack 勾上。

RUN 以后点选 Memory 并导出 Memory Graph 来观察:

由于应用程序的内存都是在 VirtualMemory 空间分配的,因此查看 VM Regions 的 VM_ALLOCATE 部分。

可以发现 128X3+16 刚好 400MB 的分配。
调用堆栈也很好确定:

正是我们的测试代码。
然后我们来看 Instruments。首先是 Allocations 部分,有一点要注意,该栏的下部有一些选项:

注意最后一个选项,如果选择第一个:
All Heap & Anonymous VM,All Heap 对应 App 实际分配的物理空间,不包含 VM,Anonymous VM 的官方解释是:

interesting VM regions such as graphics- and Core Data-related. Hides mapped files, dylibs, and some large reserved VM regions。

因此一些比较大的预留分配空间是不会显示的。

将这个选项切换为 All VM Regions,就能看到分配的 400M 了:

并且右边详情页面也正确显示了调用堆栈:

另外,我们还可以从 VM Tracker 来观察。打开 VMTracker 的 Snapshots:

就能看到这 400MB 的详细分配信息:

可以发现,Virutal Size 略大于 400MB,因为程序其他部分也要申请一些内存。而这 400MB 又分别保存在 Resident 和 Swapped 内,其中 Resident 部分又基本等于 Dirty Size,说明这部分大小的空间被标记了 Dirty 是不能被交换出去的,剩下 240MB 左右空间是 Clean 空间,可以暂时被交换出去以保证有足够的物理空间能使用。这也是因为我们只是申请了这部分空间,并没有进行具体的赋值初始化和使用。
那如果赋值使用了呢?修改代码测试

运行 Instruments 后再观察:

可以清楚的发现这 400MB 都在 Dirty Size 内。这种情况真正会给该 App 和 iOS 以内存压力。
推荐阅读:
《写给 Unity 开发者的 iOS 内存调试指南》

《Understanding iOS Memory (WiP)》

感谢黄程@UWA问答社区提供了回答


Addressable

Q:关于 Addressable v1.11.2 开始编辑器在 “Fast Mode” 模式下运行会获取 SubAsset 失败的问题。

A:今天将项目使用 Addressables 系统从 1.8.4 升级到 1.14.2。突然发现 AssetReference 指向的资源进行实例化总是报 Key 无效的错误。调查后发现从 1.11.2 开始,为了给 FastMode 进一步加速,官方修改了流程。

之前版本即使是 Fast Mode 下,也是要进行一次 Build,并且 Play 时读取 Build 出来的 Catalog,Catalog 会序列化所有的 AssetEntry 和 SubAsset,生成 ResourceLocationMap 对象然后进行检索。我们使用了不少 AssetReference 来指向 SubAsset 使用。这时使用没有问题。

1.11.2 版本开始,Fast Mode 直接提供编辑器环境下 AddressableAssetSettings 对象的 GUID 而非 Catalog 文件路径,因此 Play 后初始化时则会启用 FastMode 专用的初始化操作 FastModeInitializationOperation,这时生成的不是 ResourceLocationMap,而是 AddressableAssetSettingsLocator,这个 Locator 只是遍历了编辑器 Group 窗口对应可见的 Group 内的 AssetEntry,而 AssetEntry 内部的 SubAsset 则不会被遍历到,因此如果游戏中用到 SubAsset,就会报 Key 无效的错误。

官方 Changelog:

Refactored Play Mode Script for "Use Asset Database" to pull data directly from the settings. This reduces the time needed to enter play mode.

建议:

  • 暂时只使用 v1.8.4 版本(经项目长期使用,相对较为稳定)
  • 不建议使用 1.9.2 到 1.11.2 期间版本,还有其他 bug
  • 升级到最新的情况下,使用 Simulate Groups 模式进行开发
  • 等待官方后续改进

感谢题主黄程@UWA问答社区提供了回答


Rendering

Q:在 Unity 中自动展开 UV2(Generate Lightmap UVs),会造成个别物体的 Mesh 中顶点个数增加。

我自动展开的一个地面,顶点数从 134 变成 136,如果不展开 UV2,是没有问题的。请问,有什么办法可以在展开 UV2 时,不增加顶点个数吗?

在导入 FBX 模型时,没有勾选优化 Mesh 和其他影响顶点的一些选项。

A:因为有时候 2 个面片对应到 Lightmap 上 2 个不连续区域,而这两个面片上的顶点可能共享,因此需要拆开成 2 个顶点,其他数据一致,但是 UV2 不同。属于正常现象。

想要不增加,除非美术手动设置 UV2 并导出,即便如此,如果模型在一些面是包围闭合的,也很难保证顶点不重复。其实这个时候是顶点在 Maya 等工具内已经做了增加后导出。Unity 内可能看不出变化。

感谢黄程@UWA问答社区提供了回答


Build

Q:有没有什么办法可以提升 Unity 编辑器中代码的编译速度?我们现在每修改一次代码,等待的编译时间都将近半分钟。

A1:对于大型项目来说,这确实是大家经常遇到的情况。一般来说,Unity Editor 会按照脚本的依赖关系编译代码,其主要分为以下四个步骤:

  • 编译 Standard Assets、Pro Standard Assets 和 Plugins 文件夹中的 Runtime Script;
  • 编译以上三个文件夹中 Editor 文件夹下的 Script;
  • 编译项目中所有剩余的 Runtime Script(Editor 文件夹以外 Script);
  • 编译剩余 Script(即 Editor 文件夹中 Script)。 知道了 Unity 编辑器的脚本编译特性后,我们则建议研发团队可以将一些长时间不需要改动的脚本代码(比如各种插件代码)放入到 Standard Assets、Pro Standard Assets 或 Plugins 文件夹中,这样这些代码只需要编译一次,后续的时间就都能节省下来。

有朋友做过测试,在他们的项目中经过上面的改动,原来项目每次的编译时间从 23s 下降到 7s。想想看,这将节省你和你的团队多少时间!

推荐插件:Mad Compile Time Optimizer
推荐阅读:《优化 Unity 项目编译速度》

感谢题主 Jessica@UWA 问答社区提供了回答

A2:添加程序集定义:

https://docs.unity.cn/cn/2020.2/Manual/ScriptCompilationAssemblyDefinitionFiles.html

感谢 wangzuxiong@UWA 问答社区提供了回答

A3:拆分工程编译成不同的 DLL,Unity 2017 后可以使用引擎自带的工具定义成不同的工程。

感谢 mrchen@UWA 问答社区提供了回答


Rendering

Q:Pixel Context 是灰的:

Debug Vertex 也是灰色的:

这是为什么呢?

A1:像素调试的 Shader 里加 #pragma enable_d3d11_debug_symbols。

感谢燃野@UWA问答社区提供了回答

A2:官方文档说有说明,只能在 D3D11 或者 D3D12 中进行调试:

https://renderdoc.org/docs/how/how_debug_shader.html#hlsl-debugging

感谢 Xuan@UWA 问答社区提供了回答

封面图来源于网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在 UWA 问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之 “石”,也能攻你之 “玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官方技术 QQ 群:793972859(原群已满员)

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册