提取UnityProfiler内存数据

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingangxin666/article/details/81149565

ExtractProfilerMemory

an editor tool to save unity profiler memory

编辑器工具, 用于提取UnityProfiler内存数据

功能

  • 提取Unity Profiler窗口的内存Detailed数据
  • 支持Editor和通过IP连接手机来监测数据
  • 可以提取指定大小范围内的数据, 例如只输出内存大于1MB的数据
  • 可以指定输出的层级( 深度 ), 例如只输出2级数据
  • 输出的数据按照其占内存大小来排序

如何使用

  1. 打开窗口Window/Extract Profiler Memory

这里写图片描述
2. 选择连接的设备, Editor或手机

这里写图片描述
3. 将Profiler窗口切换到Memory视图, 并选择Detailed选项(方便数据显示)

这里写图片描述
4. 点击Take Sample, 获取内存快照
5. 选择合适的内存大小过滤和深度过滤
6. 点击Extract Memory,将数据输出到txt文件

效果截图

  1. Android环境

这里写图片描述
2. Editor环境

这里写图片描述

使用环境

Unity 5.6及以上

实现方法介绍

数据来自哪里

利用ReSharper插件的反编译功能, 可以得到UnityEditor.ProfilerWindow的CS部分的代码, 如下图

这里写图片描述

我们要提取的数据就是红框标记字段, 字段的说明如下

  • UnityEditor.ProfilerWindow: 对应Editor下的Profiler窗口
  • ProfilerWindow.m_ProfilerWindows:Profiler窗口下各种类型窗口的集合
  • ProfilerWindow.m_CurrentArea: 当前窗口的类型, 我们要提取的数据来自ProfilerArea.Memory
  • ProfilerWindow.m_MemoryListView: 内存窗口下的内存数据记录类
  • MemoryTreeList.m_Root: 记录了内存对象列表的根节点, 即所有内存对象占的总内存
  • MemoryElement.children: 当前内存对象类型包含的子内存对象
  • MemoryElement.totalMemory: 当前内存对象所占的总内存
  • MemoryElement.name: 当前内存对象的名字, 例如: Other, Assets, ShaderLab

如何提取该数据

此工具利用反射原理, 通过递归遍历MemoryElement.children来提取我们所需的数据结构totalMemory,name, totalMemory存入自定义类MemoryElement, 同时增加字段_depth来记录该内存对象的深度, 方便数据过滤

关键代码如下

    public static MemoryElement Create(Dynamic srcMemoryElement, int depth, int filterDepth, float filterSize)
    {
        if (srcMemoryElement == null) return null;
        var dstMemoryElement = new MemoryElement { _depth = depth };
        Dynamic.CopyFrom(dstMemoryElement, srcMemoryElement.InnerObject,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetField);

        var srcChildren = srcMemoryElement.PublicInstanceField<IList>("children");
        if (srcChildren == null) return dstMemoryElement;
        foreach (var srcChild in srcChildren)
        {
            var memoryElement = Create(new Dynamic(srcChild), depth + 1, filterDepth, filterSize);
            if (memoryElement == null) continue;
            if (depth > filterDepth) continue;
            if (!(memoryElement.totalMemory >= filterSize)) continue;
            dstMemoryElement.children.Add(memoryElement);
        }

        dstMemoryElement.children.Sort();
        return dstMemoryElement;
    }

参考

猜你喜欢

转载自blog.csdn.net/jingangxin666/article/details/81149565