public ObjectMapReader(string filename) { this.name = filename; currentData = new HeapShotData(); // Some stock types currentData.TypesList.Add(new TypeInfo() { Code = UnknownObjectId, Name = "<Unknown>" }); // 0 currentData.TypesList.Add(new TypeInfo() { Code = StackObjectId, Name = "<Stack>" }); // 1 currentData.TypesList.Add(new TypeInfo() { Code = FinalizerObjectId, Name = "<Finalizer>" }); // 2 currentData.TypesList.Add(new TypeInfo() { Code = HandleObjectId, Name = "<Handle>" }); // 3 currentData.TypesList.Add(new TypeInfo() { Code = OtherRootObjectId, Name = "<Other Root>" }); // 4 currentData.TypesList.Add(new TypeInfo() { Code = MiscRootObjectId, Name = "<Misc Root>" }); // 5 }
public ObjectMapReader(string filename) { this.name = filename; currentData = new HeapShotData (); // Some stock types currentData.TypesList.Add (new TypeInfo () { Code = -1, Name = "<Unknown>" }); // 0 currentData.TypesList.Add (new TypeInfo () { Code = -2, Name = "<Stack>" }); // 1 currentData.TypesList.Add (new TypeInfo () { Code = -3, Name = "<Finalizer>" }); // 2 currentData.TypesList.Add (new TypeInfo () { Code = -4, Name = "<Handle>" }); // 3 currentData.TypesList.Add (new TypeInfo () { Code = -5, Name = "<Other Root>" }); // 4 currentData.TypesList.Add (new TypeInfo () { Code = -6, Name = "<Misc Root>" }); // 5 }
internal void Build(string name, HeapShotData data) { this.name = name; // Build an array of type indices and sort it types = data.TypesList.ToArray(); TypeComparer typeComparer = new TypeComparer(); typeComparer.types = types; typeIndices = new int [types.Length]; for (int n = 0; n < types.Length; n++) { typeIndices [n] = n; } Array.Sort <int> (typeIndices, typeComparer); // Sorted array of codes needed for the binary search long[] typeCodes = new long [types.Length]; for (int n = 0; n < types.Length; n++) { typeCodes [n] = types [typeIndices[n]].Code; } // Build an array of object indices and sort it RefComparer objectComparer = new RefComparer(); objectComparer.objects = data.ObjectsList; int[] objectIndices = new int [data.ObjectsList.Count]; for (int n = 0; n < data.ObjectsList.Count; n++) { objectIndices [n] = n; } Array.Sort <int> (objectIndices, objectComparer); // Sorted array of codes needed for the reordering and binary search objectCodes = new long [data.ObjectsList.Count]; for (int n = 0; n < data.ObjectsList.Count; n++) { objectCodes [n] = data.ObjectsList [objectIndices[n]].Code; } // Merge duplicates long[] mergedObjectCodes = new long [data.RealObjectCount]; ObjectInfo[] mergedObjects = new ObjectInfo [data.RealObjectCount]; long[] mergedReferenceCodes = new long [data.ReferenceCodes.Count]; ulong[] mergedFieldReferenceCodes = new ulong [data.FieldReferenceCodes.Count]; long last = long.MinValue; int mergedObjectPos = -1; int mergedRefPos = 0; for (int n = 0; n < objectCodes.Length; n++) { ObjectInfo ob = data.ObjectsList [objectIndices[n]]; if (n == 0 || objectCodes [n] != last) { last = objectCodes [n]; mergedObjectPos++; mergedObjects [mergedObjectPos] = ob; mergedObjects [mergedObjectPos].RefsIndex = mergedRefPos; mergedObjects [mergedObjectPos].RefsCount = 0; // Refs are being added below mergedObjectCodes [mergedObjectPos] = mergedObjects [mergedObjectPos].Code; // Find the type index int i = Array.BinarySearch <long> (typeCodes, data.ObjectTypeCodes [objectIndices[n]]); if (i >= 0) { i = typeIndices [i]; mergedObjects [mergedObjectPos].Type = i; types [i].ObjectCount++; types [i].TotalSize += mergedObjects [mergedObjectPos].Size; } else { mergedObjects [mergedObjectPos].Type = 0; long type_not_found = data.ObjectTypeCodes [objectIndices [n]]; if (!types_not_found.Contains(type_not_found)) { types_not_found.Add(type_not_found); Console.WriteLine("Type not found: " + type_not_found); } } } int baseRefIndex = ob.RefsIndex; int refsCount = ob.RefsCount; for (int r = baseRefIndex; r < baseRefIndex + refsCount; r++, mergedRefPos++) { mergedReferenceCodes [mergedRefPos] = data.ReferenceCodes [r]; mergedFieldReferenceCodes [mergedRefPos] = data.FieldReferenceCodes [r]; } mergedObjects [mergedObjectPos].RefsCount += refsCount; totalMemory += mergedObjects [mergedObjectPos].Size; } objects = mergedObjects; objectCodes = mergedObjectCodes; int missingRefs = 0; // Build the array of referenceCodes, but using indexes // Also calculate the number of inverse references for each object references = new int [mergedReferenceCodes.Length]; for (int n = 0; n < mergedReferenceCodes.Length; n++) { int i = Array.BinarySearch(objectCodes, mergedReferenceCodes[n]); if (i >= 0) { references[n] = i; objects [i].InverseRefsCount++; } else { //Console.WriteLine ("Referenced object not found: " + mergedReferenceCodes[n]); references[n] = 0; missingRefs++; } } Console.WriteLine("pp Missing references: " + missingRefs + " of " + mergedReferenceCodes.Length); // Calculate the array index of inverse referenceCodes for each object int[] invPositions = new int [objects.Length]; // Temporary array to hold reference positions int rp = 0; for (int n = 0; n < objects.Length; n++) { objects [n].InverseRefsIndex = rp; invPositions [n] = rp; rp += objects [n].InverseRefsCount; } // Build the array of inverse referenceCodes // Also calculate the index of each field name inverseRefs = new int [mergedReferenceCodes.Length]; fieldReferences = new int [mergedReferenceCodes.Length]; for (int ob = 0; ob < objects.Length; ob++) { long t = objects [ob].Type; int fi = types [t].FieldsIndex; int nf = fi + types [t].FieldsCount; int sr = objects [ob].RefsIndex; int er = sr + objects [ob].RefsCount; for (; sr < er; sr++) { int i = references [sr]; if (i != -1) { inverseRefs [invPositions [i]] = ob; invPositions [i]++; } // If the reference is bound to a field, locate the field ulong fr = mergedFieldReferenceCodes [sr]; if (fr != 0) { for (int k = fi; k < nf; k++) { if (data.FieldCodes [k] == fr) { fieldReferences [sr] = k; break; } } } } } }