1、預覽&牢騷


本來標題想寫成“文本化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