private void RegisterDeallocation(UIntPtr address) { lock (this) { if (tmpEvents == null) { return; } var ev = new DeallocateEvent(address); tmpEvents.Add(ev); } }
private void RegisterDeallocation(UIntPtr address) { lock (this) { if (tmpEvents == null) return; var ev = new DeallocateEvent(address); tmpEvents.Add(ev); } }
private void ProcessAllocations() { List <HeapEvent> events = null; lock (this) { if (lastFrameEvents == null) { return; } events = lastFrameEvents; lastFrameEvents = null; } int allocCount = 0; int allocSize = 0; int deallocCount = 0; Dictionary <int, int> countForSize = new Dictionary <int, int>(); foreach (HeapEvent ev in events) { // for now if (ev is DeallocateEvent) { deallocCount++; continue; } int size = 0; if (ev is AllocateEvent) { AllocateEvent allocEv = ev as AllocateEvent; size = allocEv.Size; } else if (ev is ReallocateEvent) { ReallocateEvent reallocEv = ev as ReallocateEvent; size = reallocEv.Size; } else { throw new NotImplementedException(); } int oldCount = 0; countForSize.TryGetValue(size, out oldCount); countForSize[size] = oldCount + 1; allocCount++; allocSize += size; } StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.AppendFormat("{0} allocations ({1} bytes), {2} deallocations\r\n", allocCount, allocSize, deallocCount); sb.AppendLine(); sb.AppendLine(" Size | Count"); sb.AppendLine("------------------"); int[] sizes = countForSize.Keys.ToArray(); Array.Sort(sizes); Array.Reverse(sizes); foreach (int size in sizes) { sb.AppendFormat("{0,7} | {1}\r\n", size, countForSize[size]); } sb.AppendLine(); sb.AppendLine("Events:"); sb.AppendLine("-------"); int count = 0; foreach (HeapEvent ev in events) { sb.AppendLine(ev.ToString()); count++; if (enableEntryLimit && count >= 100) { break; } } if (enableEntryLimit) { int remaining = events.Count - count; if (remaining > 0) { sb.AppendFormat("...and {0} more...\r\n", remaining); } } List <HeapEvent> leakedEvents = new List <HeapEvent>(); foreach (HeapEvent ev in events) { UIntPtr removePtr = UIntPtr.Zero; if (ev is AllocateEvent) { AllocateEvent allocEv = ev as AllocateEvent; if (allocEv.Address != UIntPtr.Zero) { leakedEvents.Add(allocEv); } } else if (ev is ReallocateEvent) { ReallocateEvent reallocEv = ev as ReallocateEvent; if (reallocEv.NewAddress != UIntPtr.Zero) { if (reallocEv.OldAddress != UIntPtr.Zero) { if (reallocEv.NewAddress == reallocEv.OldAddress) { // no change // FIXME: in case we missed the original malloc we could get it here... } else { // relocated leakedEvents.Add(reallocEv); removePtr = reallocEv.OldAddress; } } else { // new event leakedEvents.Add(reallocEv); } } else if (reallocEv.OldAddress != UIntPtr.Zero && reallocEv.Size == 0) { // free removePtr = reallocEv.OldAddress; } } else if (ev is DeallocateEvent) { DeallocateEvent deallocEv = ev as DeallocateEvent; removePtr = deallocEv.Address; } else { throw new NotImplementedException(); } if (removePtr != UIntPtr.Zero) { bool again = false; do { again = false; foreach (HeapEvent leakEv in leakedEvents) { UIntPtr address; if (leakEv is AllocateEvent) { address = (leakEv as AllocateEvent).Address; } else if (leakEv is ReallocateEvent) { address = (leakEv as ReallocateEvent).NewAddress; } else { throw new NotImplementedException("Should not get here"); } if (address == removePtr) { leakedEvents.Remove(leakEv); again = true; break; } } }while (again); } } if (leakedEvents.Count > 0) { sb.AppendLine(); sb.AppendLine("Possible leaks:"); sb.AppendLine("---------------"); foreach (HeapEvent ev in leakedEvents) { sb.AppendLine(ev.ToString()); } } Event.InvocationOrigin origin = new Event.InvocationOrigin("HeapAgent", null, 42); PacketEvent pktEv = new PacketEvent(eventCoordinator, origin); pktEv.Data = Encoding.UTF8.GetBytes(sb.ToString()); manager.Submit(new Event[] { pktEv }); }