Skip to content

Instantly share code, notes, and snippets.

@findstr
Created October 16, 2018 09:45
Show Gist options
  • Save findstr/e41bccb0ec1486d8d4c80359e6a013b6 to your computer and use it in GitHub Desktop.
Save findstr/e41bccb0ec1486d8d4c80359e6a013b6 to your computer and use it in GitHub Desktop.
Detect Texture leak for Unity3D
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEditor;
using UnityEngine.Profiling;
namespace Profiler {
class Memory : Editor {
struct obj {
public string name;
public long size;
};
class res {
public string name;
public string type;
public int refcount;
public long size;
public res(string p1, string p2, int refcount, long size) {
this.name = p1;
this.type = p2;
this.refcount = refcount;
this.size = size;
}
};
static int compare(obj a, obj b) {
return a.name.CompareTo(b.name);
}
static Dictionary<string, res> SampleRes<T> () where T: UnityEngine.Object {
int refcount;
Dictionary<string, res> reslist = new Dictionary<string,res>();
List<obj> objlist = new List<obj>();
T[] samples = Resources.FindObjectsOfTypeAll<T>();
foreach (T t in samples) {
obj r = new obj();
r.name = t.name;
r.size = UnityEngine.Profiling.Profiler.GetRuntimeMemorySizeLong(t);
objlist.Add(r);
}
string type = typeof(T).Name;
objlist.Sort(compare);
obj last = objlist[0];
refcount = 1;
for (int i = 1; i < objlist.Count; i++) {
var obj = objlist[i];
if (obj.name.CompareTo(last.name) == 0) {
refcount++;
} else {
reslist[last.name] = new res(last.name, type, refcount, last.size);
last = obj;
refcount = 1;
}
}
reslist[last.name] = new res(last.name, type, refcount, last.size);
return reslist;
}
static void SampleWrite(string path, Dictionary<string, res> res) {
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path)) {
foreach (var pair in res) {
var v = pair.Value;
file.WriteLine(v.name + ":" + v.refcount + ":" + v.type + ":" + v.size);
}
}
}
static Dictionary<string, res> SampleRead(string path) {
Dictionary<string, res> reslist = new Dictionary<string,res>();
using (System.IO.StreamReader file = new System.IO.StreamReader(path)) {
string line;
while ((line = file.ReadLine()) != null) {
string[] field = line.Split(':');
string name = field[0];
int refcount = Int32.Parse(field[1]);
string type = field[2];
int size = Int32.Parse(field[3]);
reslist[name] = new res(name, type, refcount, size);
}
}
return reslist;
}
static string profpath = @"C:/unity.prof";
static string respath = @"C:/diff.prof";
[MenuItem("Profiler/SampleMemory")]
public static void SampleMemory() {
Dictionary<string, res> diff = new Dictionary<string,res>();
var resnow = SampleRes<Texture>();
SampleWrite(profpath, resnow);
}
[MenuItem("Profiler/DiffMemory")]
public static void DiffMemory() {
Dictionary<string, res> diff = new Dictionary<string,res>();
var resold = SampleRead(profpath);
var resnow = SampleRes<Texture>();
foreach (var pair in resnow) {
var nv = pair.Value;
res ov;
resold.TryGetValue(nv.name, out ov);
if (ov == null) {
diff[nv.name] = nv;
} else if (ov.refcount < nv.refcount) {
ov.refcount = nv.refcount - ov.refcount;
diff[nv.name] = ov;
}
}
SampleWrite(respath, diff);
}
}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment