美文网首页
Instruments如何看Mono内存分配

Instruments如何看Mono内存分配

作者: 侑虎科技 | 来源:发表于2020-09-10 16:50 被阅读0次

    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问答社区提供了回答,欢迎大家转至社区交流:
    https://answer.uwa4d.com/question/5f40a5849424416784ef1d4c


    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问答社区提供了回答,欢迎大家转至社区交流:
    https://answer.uwa4d.com/question/5f44d96a9424416784ef1efa


    Rendering

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

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

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

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

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

    感谢黄程@UWA问答社区提供了回答,欢迎大家转至社区交流:
    https://answer.uwa4d.com/question/5f436ce29424416784ef1e85


    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问答社区提供了回答,欢迎大家转至社区交流:
    https://answer.uwa4d.com/question/58d2829a9ad5c0094f461e30


    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问答社区提供了回答,欢迎大家转至社区交流:
    https://answer.uwa4d.com/question/5f3a2abf9424416784ef1c57

    封面图来源于网络


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

    官网:www.uwa4d.com
    官方技术博客:blog.uwa4d.com
    官方问答社区:answer.uwa4d.com
    UWA学堂:edu.uwa4d.com

    官方技术QQ群:793972859(原群已满员)

    相关文章

      网友评论

          本文标题:Instruments如何看Mono内存分配

          本文链接:https://www.haomeiwen.com/subject/kbvkektx.html