internal MemoryRegion(DesktopRuntimeBase clr, ulong addr, ulong size, ClrMemoryRegionType type, uint heap, GCSegmentType seg) { Address = addr; Size = size; _runtime = clr; Type = type; _domainModuleHeap = heap; _segmentType = seg; }
public bool Add(ulong address, GCSegmentType segmentType, int generation) { if (Addresses.Add(address)) { CountBySegmentType[(int)segmentType]++; CountByGeneration[generation + 1]++; return(true); } return(false); }
/// <summary> /// Enumerates regions of memory which CLR has allocated with a description of what data /// resides at that location. Note that this does not return every chunk of address space /// that CLR allocates. /// </summary> /// <returns>An enumeration of memory regions in the process.</returns> public override IEnumerable <ClrMemoryRegion> EnumerateMemoryRegions() { // Enumerate GC Segment regions. IHeapDetails[] heaps; if (ServerGC) { heaps = new IHeapDetails[HeapCount]; int i = 0; ulong[] heapList = GetServerHeapList(); if (heapList != null) { foreach (ulong addr in heapList) { heaps[i++] = GetSvrHeapDetails(addr); if (i == heaps.Length) { break; } } } else { heaps = new IHeapDetails[0]; } } else { Debug.Assert(HeapCount == 1); heaps = new IHeapDetails[1]; heaps[0] = GetWksHeapDetails(); } HashSet <ulong> addresses = new HashSet <ulong>(); for (int i = 0; i < heaps.Length; ++i) { // Small heap ISegmentData segment = GetSegmentData(heaps[i].FirstHeapSegment); while (segment != null) { Debug.Assert(segment.Start < segment.Committed); GCSegmentType type = segment.Address == heaps[i].EphemeralSegment ? GCSegmentType.Ephemeral : GCSegmentType.Regular; yield return(new MemoryRegion(this, segment.Start, segment.Committed - segment.Start, ClrMemoryRegionType.GCSegment, (uint)i, type)); if (segment.Committed <= segment.Reserved) { yield return(new MemoryRegion(this, segment.Committed, segment.Reserved - segment.Committed, ClrMemoryRegionType.ReservedGCSegment, (uint)i, type)); } if (segment.Address == segment.Next || segment.Address == 0) { break; } if (!addresses.Add(segment.Next)) { break; } segment = GetSegmentData(segment.Next); } segment = GetSegmentData(heaps[i].FirstLargeHeapSegment); while (segment != null) { Debug.Assert(segment.Start < segment.Committed); yield return(new MemoryRegion(this, segment.Start, segment.Committed - segment.Start, ClrMemoryRegionType.GCSegment, (uint)i, GCSegmentType.LargeObject)); if (segment.Committed <= segment.Reserved) { yield return(new MemoryRegion( this, segment.Committed, segment.Reserved - segment.Committed, ClrMemoryRegionType.ReservedGCSegment, (uint)i, GCSegmentType.LargeObject)); } if (segment.Address == segment.Next || segment.Address == 0) { break; } if (!addresses.Add(segment.Next)) { break; } segment = GetSegmentData(segment.Next); } } // Enumerate handle table regions. HashSet <ulong> regions = new HashSet <ulong>(); foreach (ClrHandle handle in EnumerateHandles()) { if (!_dataReader.VirtualQuery(handle.Address, out VirtualQueryData vq)) { continue; } if (regions.Contains(vq.BaseAddress)) { continue; } regions.Add(vq.BaseAddress); yield return(new MemoryRegion(this, vq.BaseAddress, vq.Size, ClrMemoryRegionType.HandleTableChunk, handle.AppDomain)); } // Enumerate each AppDomain and Module specific heap. AppDomainHeapWalker adhw = new AppDomainHeapWalker(this); IAppDomainData ad = GetAppDomainData(SystemDomainAddress); foreach (MemoryRegion region in adhw.EnumerateHeaps(ad)) { yield return(region); } foreach (ulong module in EnumerateModules(ad)) { foreach (MemoryRegion region in adhw.EnumerateModuleHeaps(ad, module)) { yield return(region); } } ad = GetAppDomainData(SharedDomainAddress); foreach (MemoryRegion region in adhw.EnumerateHeaps(ad)) { yield return(region); } foreach (ulong module in EnumerateModules(ad)) { foreach (MemoryRegion region in adhw.EnumerateModuleHeaps(ad, module)) { yield return(region); } } IAppDomainStoreData ads = GetAppDomainStoreData(); if (ads != null) { ulong[] appDomains = GetAppDomainList(ads.Count); if (appDomains != null) { foreach (ulong addr in appDomains) { ad = GetAppDomainData(addr); foreach (MemoryRegion region in adhw.EnumerateHeaps(ad)) { yield return(region); } foreach (ulong module in EnumerateModules(ad)) { foreach (MemoryRegion region in adhw.EnumerateModuleHeaps(ad, module)) { yield return(region); } } } } } // Enumerate each JIT code heap. regions.Clear(); foreach (ICodeHeap jitHeap in EnumerateJitHeaps()) { if (jitHeap.Type == CodeHeapType.Host) { if (_dataReader.VirtualQuery(jitHeap.Address, out VirtualQueryData vq)) { yield return(new MemoryRegion(this, vq.BaseAddress, vq.Size, ClrMemoryRegionType.JitHostCodeHeap)); } else { yield return(new MemoryRegion(this, jitHeap.Address, 0, ClrMemoryRegionType.JitHostCodeHeap)); } } else if (jitHeap.Type == CodeHeapType.Loader) { foreach (MemoryRegion region in adhw.EnumerateJitHeap(jitHeap.Address)) { yield return(region); } } } }