Пример #1
0
        internal bool GetHeaps(out SubHeap[] heaps)
        {
            heaps = new SubHeap[HeapCount];
            Dictionary <ulong, ulong> allocContexts = GetAllocContexts();

            if (ServerGC)
            {
                ulong[] heapList = GetServerHeapList();
                if (heapList == null)
                {
                    return(false);
                }

                bool succeeded = false;
                for (int i = 0; i < heapList.Length; ++i)
                {
                    IHeapDetails heap = GetSvrHeapDetails(heapList[i]);
                    if (heap == null)
                    {
                        continue;
                    }

                    heaps[i] = new SubHeap(heap, i);
                    heaps[i].AllocPointers = new Dictionary <ulong, ulong>(allocContexts);
                    if (heap.EphemeralAllocContextPtr != 0)
                    {
                        heaps[i].AllocPointers[heap.EphemeralAllocContextPtr] = heap.EphemeralAllocContextLimit;
                    }

                    succeeded = true;
                }

                return(succeeded);
            }
            else
            {
                Debug.Assert(HeapCount == 1);

                IHeapDetails heap = GetWksHeapDetails();
                if (heap == null)
                {
                    return(false);
                }

                heaps[0] = new SubHeap(heap, 0);
                heaps[0].AllocPointers = allocContexts;
                heaps[0].AllocPointers[heap.EphemeralAllocContextPtr] = heap.EphemeralAllocContextLimit;

                return(true);
            }
        }
Пример #2
0
        /// <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);
                    }
                }
            }
        }
Пример #3
0
        /// <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;
                Address[] 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();
            }

            int max = 2048;  // Max number of segments in case of inconsistent data.
            for (int i = 0; i < heaps.Length; ++i)
            {
                // Small heap
                ISegmentData segment = GetSegmentData(heaps[i].FirstHeapSegment);
                while (segment != null && max-- > 0)
                {
                    Debug.Assert(segment.Start < segment.Committed);
                    Debug.Assert(segment.Committed <= segment.Reserved);

                    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);
                    yield return new MemoryRegion(this, segment.Committed, segment.Reserved - segment.Committed, ClrMemoryRegionType.ReservedGCSegment, (uint)i, type);

                    if (segment.Address == segment.Next || segment.Address == 0)
                        segment = null;
                    else
                        segment = GetSegmentData(segment.Next);
                }

                segment = GetSegmentData(heaps[i].FirstLargeHeapSegment);
                while (segment != null && max-- > 0)
                {
                    Debug.Assert(segment.Start < segment.Committed);
                    Debug.Assert(segment.Committed <= segment.Reserved);

                    yield return new MemoryRegion(this, segment.Start, segment.Committed - segment.Start, ClrMemoryRegionType.GCSegment, (uint)i, GCSegmentType.LargeObject);
                    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)
                        segment = null;
                    else
                        segment = GetSegmentData(segment.Next);
                }
            }

            // Enumerate handle table regions.
            HashSet<ulong> regions = new HashSet<ulong>();
            foreach (ClrHandle handle in EnumerateHandles())
            {
                VirtualQueryData vq;
                if (!_dataReader.VirtualQuery(handle.Address, out 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)
            {
                IList<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)
                {
                    VirtualQueryData vq;
                    if (_dataReader.VirtualQuery(jitHeap.Address, out 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;
                }
            }
        }
Пример #4
0
 internal SubHeap(IHeapDetails heap, int heapNum)
 {
     ActualHeap = heap;
     HeapNum = heapNum;
 }
Пример #5
0
 internal SubHeap(IHeapDetails heap, int heapNum, Dictionary <ulong, ulong> allocPointers)
 {
     ActualHeap    = heap;
     HeapNum       = heapNum;
     AllocPointers = allocPointers;
 }
Пример #6
0
 internal SubHeap(IHeapDetails heap, int heapNum)
 {
     ActualHeap = heap;
     HeapNum    = heapNum;
 }