public void Find(ObjectProxy obj) { m_IsBusy = true; m_Items = new List <RootPath>(); var seen = new HashSet <long>(); var queue = new Queue <List <ObjectProxy> >(); queue.Enqueue(new List <ObjectProxy> { obj }); int guard = 0; while (queue.Any()) { if (m_Abort) { break; } if (++guard > s_IterationLoopGuard) { Debug.LogWarning("RootPath iteration loop guard kicked in."); //m_Items = new List<RootPath>(); break; } var pop = queue.Dequeue(); var tip = pop.Last(); RootPathReason reason; if (IsRoot(tip, out reason)) { m_Items.Add(new RootPath(reason, pop.ToArray())); continue; } var referencedBy = GetReferencedBy(tip); foreach (var next in referencedBy) { if (seen.Contains(next.id)) { continue; } seen.Add(next.id); var dupe = new List <ObjectProxy>(pop) { next }; queue.Enqueue(dupe); m_ScanCount++; } } m_Items.Sort(); m_IsBusy = false; }
void ScheduleJob(ObjectProxy objectProxy) { var job = new Job { snapshot = snapshot, objectProxy = objectProxy, referencedByControl = m_ReferencedByControl, referencesControl = m_ReferencesControl }; ScheduleJob(job); }
void ScheduleJob(ObjectProxy objectProxy) { Clear(); var job = new RootPathJob { snapshot = snapshot, objectProxy = objectProxy, control = m_RootPathControl, paths = m_RootPaths }; ScheduleJob(job); }
List <ObjectProxy> GetReferencedBy(ObjectProxy obj) { var referencedBy = new List <PackedConnection>(32); if (obj.staticField.isValid) { obj.snapshot.GetConnections(obj.staticField.packed, null, referencedBy); } if (obj.native.isValid) { obj.snapshot.GetConnections(obj.native.packed, null, referencedBy); } if (obj.managed.isValid) { obj.snapshot.GetConnections(obj.managed.packed, null, referencedBy); } if (obj.gcHandle.isValid) { obj.snapshot.GetConnections(obj.gcHandle.packed, null, referencedBy); } var value = new List <ObjectProxy>(referencedBy.Count); foreach (var c in referencedBy) { switch (c.fromKind) { case PackedConnection.Kind.Native: value.Add(new ObjectProxy(obj.snapshot, obj.snapshot.nativeObjects[c.from])); break; case PackedConnection.Kind.Managed: value.Add(new ObjectProxy(obj.snapshot, obj.snapshot.managedObjects[c.from])); break; case PackedConnection.Kind.GCHandle: value.Add(new ObjectProxy(obj.snapshot, obj.snapshot.gcHandles[c.from])); break; case PackedConnection.Kind.StaticField: value.Add(new ObjectProxy(obj.snapshot, obj.snapshot.managedStaticFields[c.from])); break; } } return(value); }
bool IsRoot(ObjectProxy thing, out RootPathReason reason) { reason = RootPathReason.None; if (thing.staticField.isValid) { reason = RootPathReason.Static; return(true); } if (thing.managed.isValid) { return(false); } if (thing.gcHandle.isValid) { return(false); } if (!thing.native.isValid) { throw new System.ArgumentException("Unknown type: " + thing.GetType()); } if (thing.native.isManager) { reason = RootPathReason.UnityManager; return(true); } if (thing.native.isDontDestroyOnLoad) { reason = RootPathReason.DontDestroyOnLoad; return(true); } if ((thing.native.hideFlags & HideFlags.DontUnloadUnusedAsset) != 0) { reason = RootPathReason.DontUnloadUnusedAsset; return(true); } if (thing.native.isPersistent) { return(false); } if (thing.native.type.IsSubclassOf(thing.snapshot.coreTypes.nativeComponent)) { reason = RootPathReason.Component; return(true); } if (thing.native.type.IsSubclassOf(thing.snapshot.coreTypes.nativeGameObject)) { reason = RootPathReason.GameObject; return(true); } if (thing.native.type.IsSubclassOf(thing.snapshot.coreTypes.nativeAssetBundle)) { reason = RootPathReason.AssetBundle; return(true); } reason = RootPathReason.Unknown; return(true); }
public void Find(ObjectProxy obj) { m_IsBusy = true; m_Items = new List <RootPath>(); var seen = new HashSet <long>(); var queue = new Queue <List <ObjectProxy> >(); queue.Enqueue(new List <ObjectProxy> { obj }); int issues = 0; int guard = 0; while (queue.Any()) { if (m_Abort) { break; } if (++guard > s_IterationLoopGuard) { Debug.LogWarning("RootPath iteration loop guard kicked in."); //m_Items = new List<RootPath>(); break; } var pop = queue.Dequeue(); var tip = pop.Last(); RootPathReason reason; if (IsRoot(tip, out reason)) { m_Items.Add(new RootPath(reason, pop.ToArray())); continue; } var referencedBy = GetReferencedBy(tip, ref issues); foreach (var next in referencedBy) { if (seen.Contains(next.id)) { continue; } seen.Add(next.id); var dupe = new List <ObjectProxy>(pop) { next }; queue.Enqueue(dupe); m_ScanCount++; } } m_Items.Sort(); m_IsBusy = false; if (issues > 0) { Debug.LogWarningFormat("{0} issues have been detected while finding root-paths. This is most likely related to an earlier bug in Heap Explorer, that started to occur with Unity 2019.3 and causes that (some) object connections are invalid. Please capture a new memory snapshot.", issues); } }