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); }
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); }
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()); }
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++; }
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); }