public static Snapshot GetIntersection(Snapshot first, Snapshot second) { if (first.index.Count > second.index.Count) { Snapshot temp = first; first = second; second = temp; } Snapshot snapshot = new Snapshot(); foreach (SnapshotNode node in first.index.Values) { if (second.index.ContainsKey(node.id)) { snapshot.index[node.id] = node; } } if (snapshot.index.Count == 0) { SnapshotNode temp = new SnapshotNode(0, 0, 0, new long[] { 0 }, new string[] { "Empty" }); snapshot.index[temp.id] = temp; } snapshot.list = snapshot.index.Values.ToList(); snapshot.list.Sort(); return(snapshot); }
protected override void OnNodeChange(SnapshotNode node) { if (snapshot.index.ContainsKey(node.id)) { selectedItem = items.First(i => i.node == node); selectedGroup = selectedItem.group; RefreshCachedRects(false); } else { Debugger.LogError("该快照不含该值,需要在之后的版本中改进"); } }
public override void Draw(Rect area) { GUILayout.BeginArea(area); scrollPosition = GUILayout.BeginScrollView(scrollPosition); if (selectedNode == null) { GUILayout.Label("Select an object to see more info"); } else { EditorGUILayout.LabelField(string.Format("Name: {0}", selectedNode.GetName(0))); EditorGUILayout.LabelField(string.Format("Other Name: ")); selectedNode.GetDistinctName().ForEach(c => EditorGUILayout.LabelField(" " + c)); EditorGUILayout.LabelField(string.Format("Type: {0}", selectedNode.type.ToString())); EditorGUILayout.LabelField(string.Format("Size: {0} ({1} Byte)", EditorUtility.FormatBytes(selectedNode.thisNodeSize), selectedNode.thisNodeSize.ToString())); EditorGUILayout.LabelField(string.Format("TotalSize: {0} ({1} Byte)", EditorUtility.FormatBytes(selectedNode.totalSize), selectedNode.totalSize.ToString())); EditorGUILayout.LabelField("Reference: "); foreach (SnapshotNode child in selectedNode.children) { if (GUILayout.Button(child.GetName(selectedNode.id))) { if (NodeChangeEvent != null) { NodeChangeEvent(child); } } } EditorGUILayout.LabelField("Reference By: "); foreach (long parent in selectedNode.parents) { if (!snapshot.index.ContainsKey(parent)) { continue; } SnapshotNode node = snapshot.index[parent]; if (GUILayout.Button(node.GetName(selectedNode.id))) { if (NodeChangeEvent != null) { NodeChangeEvent(node); } } } } GUILayout.EndScrollView(); GUILayout.EndArea(); }
protected void Draw(SnapshotNode node, long parentId) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(" ", GUILayout.Width(10)); EditorGUILayout.BeginVertical(); string text = string.Format("{0} size:{1}({2}B) total size:{3}({4}B)", node.GetName(parentId), EditorUtility.FormatBytes(node.thisNodeSize), node.thisNodeSize, EditorUtility.FormatBytes(node.totalSize), node.totalSize); bool isFold = true; if (node.children.Count > 0) { if (isFoldSet.Contains(node)) { isFold = false; } isFold = !EditorGUILayout.Foldout(!isFold, text); if (!isFold) { isFoldSet.Add(node); } else { if (isFoldSet.Contains(node)) { isFoldSet.Remove(node); } } } else { EditorGUILayout.LabelField(text); } if (!isFold) { for (int i = 0; i < node.children.Count; i++) { Draw(node.children[i], node.id); } } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); }
private static void RemoveCircle(SnapshotNode root) { Queue <SnapshotNode> BFSQueue = new Queue <SnapshotNode>(); int tempNum = 1; root.isVisitedInRemoveCircle = true; BFSQueue.Enqueue(root); while (BFSQueue.Count != 0) { SnapshotNode node = BFSQueue.Dequeue(); tempNum--; node.children.RemoveAll(c => c.isVisitedInRemoveCircle); node.children.ForEach(c => BFSQueue.Enqueue(c)); if (tempNum == 0) { foreach (SnapshotNode queueNode in BFSQueue) { queueNode.isVisitedInRemoveCircle = true; } tempNum = BFSQueue.Count; } } }
public static Snapshot GetDifferenceSet(Snapshot first, Snapshot second) { Snapshot snapshot = new Snapshot(); foreach (SnapshotNode node in first.index.Values) { if (!second.index.ContainsKey(node.id)) { snapshot.index[node.id] = node; } else if (Setting.IS_DIFF_SET_CHECK_MEMORY && node.thisNodeSize != second.index[node.id].thisNodeSize) { snapshot.index[node.id] = node; } } if (snapshot.index.Count == 0) { SnapshotNode temp = new SnapshotNode(0, 0, 0, new long[] { 99999999 }, new string[] { "Empty" }); snapshot.index[temp.id] = temp; } snapshot.list = snapshot.index.Values.ToList(); snapshot.list.Sort(); return(snapshot); }
public static Snapshot GetSnapshot(LuaState lua) { if (snapshot_capture(lua.L) == -1) { return(null); } int number = snapshot_get_gcobj_num(); if (number == -1) { return(null); } Snapshot snapshot = new Snapshot(); //将c结构转换为c#结构 int wrapperSize = Marshal.SizeOf(typeof(SnapshotNodeWrapper)); IntPtr wrapperPtr = Marshal.AllocHGlobal(wrapperSize * number); snapshot_get_gcobjs(number, wrapperPtr); for (int i = 0; i < number; i++) { SnapshotNodeWrapper wrapper = (SnapshotNodeWrapper)Marshal.PtrToStructure((IntPtr)((UInt32)wrapperPtr + i * wrapperSize), typeof(SnapshotNodeWrapper)); SnapshotNode node = new SnapshotNode(wrapper.address.ToInt64(), wrapper.type, wrapper.size, new long[wrapper.parentNum], new string[wrapper.parentNum]); for (int j = 0; j < wrapper.parentNum; j++) { node.parents[j] = ((IntPtr)Marshal.PtrToStructure((IntPtr)((UInt32)wrapper.parents + j * Marshal.SizeOf(typeof(IntPtr))), typeof(IntPtr))).ToInt64(); node.reference[j] = Marshal.PtrToStringAnsi((IntPtr)Marshal.PtrToStructure((IntPtr)((UInt32)wrapper.reference + j * Marshal.SizeOf(typeof(IntPtr))), typeof(IntPtr))); } snapshot.index[node.id] = node; } foreach (KeyValuePair <long, SnapshotNode> kyPair in snapshot.index) { SnapshotNode thisNode = kyPair.Value; for (int i = 0; i < thisNode.parents.Length; i++) { if (thisNode.parents[i] == 0) { snapshot.root = thisNode; } if (!snapshot.index.ContainsKey(thisNode.parents[i])) { thisNode.nameDict[thisNode.parents[i]] = thisNode.reference[i]; continue; } snapshot.index[thisNode.parents[i]].children.Add(thisNode); thisNode.nameDict[thisNode.parents[i]] = thisNode.reference[i]; } } RemoveCircle(snapshot.root); foreach (SnapshotNode node in snapshot.index.Values) { node.children.Sort(); } snapshot.name = DateTime.Now.ToShortTimeString(); snapshot_clear(); return(snapshot); }
protected virtual void OnNodeChange(SnapshotNode node) { }
protected override void OnNodeChange(SnapshotNode node) { this.selectedNode = node; }
protected override void OnSnapshotChange(Snapshot snapshot) { this.snapshot = snapshot; this.selectedNode = null; }
public Item(SnapshotNode node, Group group) { this.node = node; this.group = group; }
private string GetGroupName(SnapshotNode node) { string name = ""; switch (node.type) { case SnapshotType.SNAPSHOT_C_FUNCTION: if (node.thisNodeSize > 500) { name = "Big C Function (size > 500B)"; } else { name = "Small C Function (size <= 500B)"; } break; case SnapshotType.SNAPSHOT_LUA_FUNCTION: if (node.thisNodeSize > 500) { name = "Big Lua Function (size > 500B)"; } else { name = "Small Lua Function (size <= 500B)"; } break; case SnapshotType.SNAPSHOT_MASK: name = "Mask"; break; case SnapshotType.SNAPSHOT_STRING: if (node.thisNodeSize > 500) { name = "Big String (size > 500B)"; } else { name = "Small String (size <= 500B)"; } break; case SnapshotType.SNAPSHOT_TABLE: if (node.thisNodeSize > 500) { name = "Big Table (size > 500B)"; } else if (node.thisNodeSize <= 500 && node.thisNodeSize > 100) { name = "Middle Table (100B < size <= 500B)"; } else { name = "Small Table (size <= 100B)"; } break; case SnapshotType.SNAPSHOT_THREAD: name = "Thread"; break; case SnapshotType.SNAPSHOT_USERDATA: name = "User Data"; break; } return(name); }