Пример #1
0
        public void No_Reference_Allows_GC()
        {
            var obj = new Object();
            var gcTester = new GCWatch(obj);

            obj = null;

            Assert.IsTrue(gcTester.IsEligibleForGC());
        }
        public void GivenLazyTransformStreamWithStream_WhenDisposing_IsDisposedCorrectly()
        {
            var     inputStream = _recyclableMemoryStreamManager.GetStream("GivenLazyTransformStreamWithStream_WhenDisposing_IsDisposedCorrectly.TestData", TestData, 0, TestData.Length);
            GCWatch gcWatch     = GetGCWatch(inputStream, ReadAndCreateNewStream);

            inputStream.Dispose();
            inputStream = null;
            Assert.True(gcWatch.IsAlive);
        }
Пример #3
0
        public void Reference_Keeps_Object_Alive_Or_Not()
        {
            var obj = new Object();
            var gcTester = new GCWatch(obj);

            #if DEBUG
            Assert.IsFalse(gcTester.IsEligibleForGC());
            #else
            Assert.IsTrue(gcTester.IsEligibleForGC());
            #endif
        }
        private static GCWatch GetGCWatch <T>(T inputData, Func <T, Stream> transformFunction)
        {
            var lazyTransform = new LazyTransformReadOnlyStream <T>(inputData, transformFunction);
            var result        = new GCWatch(lazyTransform);

            // Read the entire stream
            var outputBuffer = new byte[lazyTransform.Length];

            lazyTransform.Read(outputBuffer, 0, outputBuffer.Length);

            return(result);
        }
Пример #5
0
        public void GC_Collects_Graph()
        {
            var foo1 = new Foo();
            var foo2 = new Foo();

            var gcTester1 = new GCWatch(foo1);
            var gcTester2 = new GCWatch(foo2);

            foo1.objects.Add(foo2);
            foo2.objects.Add(foo1);

            foo1 = null;
            Assert.IsFalse(gcTester1.IsEligibleForGC());
            Assert.IsFalse(gcTester2.IsEligibleForGC());
            GC.KeepAlive(foo2);

            foo2 = null;
            Assert.IsTrue(gcTester1.IsEligibleForGC());
            Assert.IsTrue(gcTester2.IsEligibleForGC());
        }
Пример #6
0
        public static void CollectGarbage()
        {
            GCWatch.Start();

            // 从stack出发
            foreach (var thread in ThreadManager.Threads)
            {
                // 要保证GC执行期间线程全部停止
                for (uint i = 0; i < thread.Stack.SP; ++i)
                {
                    if (thread.Stack.Slots[i].DataTag == SlotDataTag.ADDRESS)
                    {
                        MarkObject(thread.Stack.GetAddress(i));
                    }
                }
            }

            // 从类的静态区出发
            foreach (var staticClassData in StaticArea.Singleton.DataMap.Values)
            {
                uint addr = MemoryMap.MapToAbsolute(staticClassData.Offset, MemoryTag.STATIC);
                ModuleLoader.Classes.TryGetValue(addr, out VMClass vmClass);
                foreach (var staticField in vmClass.StaticFields)
                {
                    if (staticField.Type.Tag == VariableTypeTag.ADDRESS)
                    {
                        // 是地址
                        MarkObject(BitConverter.ToUInt32(staticClassData.Data, staticField.Offset));
                    }
                }
            }

            // 回收
            LinkedListNode <HeapData> cur = Heap.Singleton.Data.First;

            while (cur != null)
            {
                if ((cur.Value.GCInfo & (uint)GCTag.GCMark) == 0)
                {
                    // 不可达对象,删除
                    LinkedListNode <HeapData> tmp = cur;
                    cur = cur.Next;
                    Heap.Singleton.DataMap.Remove(tmp.Value.Offset);
                    Heap.Singleton.Data.Remove(tmp);
                    Heap.Singleton.Size -= tmp.Value.Data.Length;
                    FreedSize           += tmp.Value.Data.Length / 1024;
                }
                else
                {
                    // 清除GCMark
                    cur.Value.GCInfo = cur.Value.GCInfo & (~(uint)GCTag.GCMark);
                    cur = cur.Next;
                }
            }

            GCWatch.Stop();
            GCTotalTime += GCWatch.ElapsedMilliseconds;
            if (GCWatch.ElapsedMilliseconds > GCMaxTime)
            {
                GCMaxTime = GCWatch.ElapsedMilliseconds;
            }
            GCCount++;
        }
Пример #7
0
        public void Usable_Reference_Keeps_Object_Alive()
        {
            var obj = new Object();
            var gcTester = new GCWatch(obj);

            Assert.IsFalse(gcTester.IsEligibleForGC());

            GC.KeepAlive(obj);
        }
        public void GivenLazyTransformStreamWithByteArray_WhenDisposing_IsDisposedCorrectly()
        {
            GCWatch gcWatch = GetGCWatch(TestData, ReverseByteArray);

            Assert.True(gcWatch.IsAlive);
        }