[Unity Editor] 提取Profiler數(shù)據(jù) - Memory

1、預覽&牢騷

Profiler信息.png
提取后存儲的文本.png

本來標題想寫成“文本化XXX”,看上去有逼格,后來想想沒啥卵用,還可能無法準確表達文章內(nèi)容,最終用了更符合我初始目的的詞 - 提取數(shù)據(jù)。
  上面兩張圖應能很好的表達出這個工具的功能了 - 從Profiler中提取詳細(Detailed)內(nèi)存信息,然后寫入文件。
  這個工具來源于我自己工作的需要。項目中做資源管理優(yōu)化時,要檢查內(nèi)存中資源冗余的情況,還要對比不同場景間資源使用的差異(主要關(guān)注是否有沒被卸載的情況)。實際檢查要在Profiler的幾百條數(shù)據(jù)里找問題,Profiler是按內(nèi)存大小進行排序的,查找高占用的資源非常方便,但是對這種檢查工作就非常不友好。第一次看的時候眼睛都要瞎了,一條條的看數(shù)據(jù),甚是惡心Orm……當時就想要是能把這些數(shù)據(jù)搞到文件里,至少還能用個Ctrl+F吧。結(jié)果找了一圈也沒發(fā)現(xiàn)做法,只能忍著惡心完成了第一次檢查。
  可喜的是,在后面做Debug封裝的時候找到了思路,感謝這個朋友的文章:解決在Unity中封裝Debug.Log后代碼行定位問題

2、實戰(zhàn)

這個工具的思路非常簡單:借助反射大法,調(diào)用UnityEditor里的內(nèi)容
  我覺得這塊內(nèi)容,到這里就可以結(jié)束了……有技術(shù)含量的內(nèi)容已經(jīng)寫完!不過一句話作為一個小節(jié)也挺尷尬,下面介紹下如何定位到需要的代碼位置。
  首先是工具,反射好用,但也得知道要反射的結(jié)果是什么。我記得上面的文章是通過打印類成員的方式來定位的,這樣確實可以,不過(開發(fā))效率很低。我使用的是VS的一個插件,叫ReSharper,它的Assembly Explorer可以反編譯DLL,不僅能看到成員名還能看到代碼,非常方便!
  接下來列舉代碼上幾個關(guān)鍵的位置,權(quán)當湊字數(shù)了(突然想起當前寫作文的感受Orm)。

  • class ProfilerWindow:Profiler窗口的內(nèi)容,都可以把這個類作為入口
  • ProfilerWindow.m_ProfilerWindows:存儲所有當前打開的子窗口,有CPU、Memory等
  • ProfilerWindow.m_MemoryListView:這個對象里,存儲了Memory Detailed采樣后的數(shù)據(jù)
  • MemoryTreeListClickable.m_Root:Detailed層次結(jié)構(gòu)的根節(jié)點,每個MemoryElement對象記錄了一條數(shù)據(jù)。

3、使用

這篇文章不打算給出任何工具實現(xiàn)的代碼,因為上面把漁都給出來了。生魚不給,最后會給條熟魚,方便快速使用。

/// <summary>
/// 提取Profiler內(nèi)存數(shù)據(jù)
/// </summary>
[MenuItem("Tools/Profiler/Extract Memory")]
public static void ExtractMemory()
{
    // 數(shù)據(jù)過濾器,只提取這里名稱匹配的層次
    Dictionary<int, HashSet<string>> filter = new Dictionary<int, HashSet<string>>()
    {
        {1, new HashSet<string>() {"Assets",}}, //"Other", "Not Saved"
        {2, new HashSet<string>()
            {
                "SerializedFile",
                "Texture2D",
            }
        },
    };

    MemoryElement root = ProfilerWindow.GetMemoryDetailRoot(filter);
    if (null != root)
    {
        string path = Path.Combine(OutputPath, "Mem Detailed.txt");
        using (StreamWriter writer = new StreamWriter(path))
        {
            ProfilerWindow.WriteMemoryDetail(writer, root);
        }
    }
    Debug.Log("Save Memory Datas Finish.");
}

我工具里對數(shù)據(jù)做了幾處小處理:

  • 排序:我使用節(jié)點名稱的字典序排序的,這樣輸出后,查找冗余資源會方便很多;資源對比,借助BeyondCompare也很方便。
  • 過濾:添加了簡單的過濾條件,就是上面代碼中的filter。實際項目中Profiler數(shù)據(jù)達到幾W條很輕松,但是通常并不需要關(guān)注全部的,只要把大頭解決就好。

使用步驟:
1)打開Profiler - Memory - Detailed,自己點Take Sample
2)數(shù)據(jù)出來后,點Tools/Profiler/Extract Memory按鈕

這是我編譯好的DLL庫(熟魚),可以直接拿來用(XML是注釋文檔)
EditorToolkit - ExtractMemory.dll
EditorToolkit - ExtractMemory.xml

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容