为什么 net core 2.0 中的垃圾收集器不释放所有内存
Why doesn't garbage collector in net core 2.0 free all memory
我是 运行 net core 2.0 上的简单代码,在垃圾收集后我的程序仍然消耗 140 MB 的内存。有谁知道为什么以及如何减少它?我也有附带问题。控制台应用程序和 Web 应用程序中的垃圾收集之间有什么区别吗?
var rand = new Random();
var list = new List<Test>();
for(int i = 0; i < 10_000_000; i++)
{
list.Add( new Test {
Id = i,
Number = rand.NextDouble(),
Number1 = rand.NextDouble(),
Number2 = rand.NextDouble(),
Number3 = rand.NextDouble(),
Number4 = rand.NextDouble(),
Number5 = rand.NextDouble(),
Number6 = rand.NextDouble(),
Number7 = rand.NextDouble(),
Number8 = rand.NextDouble(),
});
}
Console.WriteLine("End of generation");
Console.ReadLine();
for(int i = 0; i < list.Count; i++)
{
list[i] = null;
}
list = null;
GC.Collect(1);
GC.WaitForPendingFinalizers();
GC.Collect(2);
GC.WaitForPendingFinalizers();
GC.Collect(3);
GC.WaitForPendingFinalizers();
Console.ReadLine();
我测试了你的代码,确实和你描述的一样。拍了一张快照,看了一下对象,内存里还有一个List<Test>
。
如果您 运行 它处于释放模式,所有内存都会按预期释放。
所以我猜,这是调试模式下的 bug 行为。
编辑::
Debug extends the lifetime for some objects to the end of the method to allow you to inspect variables.
我对其进行了测试,如果将生成列表的代码放在单独的方法中,所有内存都会被释放。
如果此引用类型(列表)是此方法的本地引用类型,JIT 编译器实际上可以在堆栈而不是堆上分配它,并且 Console.Readline();
堆栈永远不会被释放,但我真的不知道如何你测试一下。
关于 GC 之间的区别,是的,我认为我们公司曾经遇到过问题,我们实际上发现控制台应用程序的 GC 与 Web 应用程序的不同。据我所知,Web 应用程序中的 GC 是 运行 服务器模式,但不记得控制台应用程序的 GC 模式。
更多关于 GC 模式的信息:https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/
我是 运行 net core 2.0 上的简单代码,在垃圾收集后我的程序仍然消耗 140 MB 的内存。有谁知道为什么以及如何减少它?我也有附带问题。控制台应用程序和 Web 应用程序中的垃圾收集之间有什么区别吗?
var rand = new Random();
var list = new List<Test>();
for(int i = 0; i < 10_000_000; i++)
{
list.Add( new Test {
Id = i,
Number = rand.NextDouble(),
Number1 = rand.NextDouble(),
Number2 = rand.NextDouble(),
Number3 = rand.NextDouble(),
Number4 = rand.NextDouble(),
Number5 = rand.NextDouble(),
Number6 = rand.NextDouble(),
Number7 = rand.NextDouble(),
Number8 = rand.NextDouble(),
});
}
Console.WriteLine("End of generation");
Console.ReadLine();
for(int i = 0; i < list.Count; i++)
{
list[i] = null;
}
list = null;
GC.Collect(1);
GC.WaitForPendingFinalizers();
GC.Collect(2);
GC.WaitForPendingFinalizers();
GC.Collect(3);
GC.WaitForPendingFinalizers();
Console.ReadLine();
我测试了你的代码,确实和你描述的一样。拍了一张快照,看了一下对象,内存里还有一个List<Test>
。
如果您 运行 它处于释放模式,所有内存都会按预期释放。
所以我猜,这是调试模式下的 bug 行为。
编辑:
Debug extends the lifetime for some objects to the end of the method to allow you to inspect variables.
我对其进行了测试,如果将生成列表的代码放在单独的方法中,所有内存都会被释放。
如果此引用类型(列表)是此方法的本地引用类型,JIT 编译器实际上可以在堆栈而不是堆上分配它,并且 Console.Readline();
堆栈永远不会被释放,但我真的不知道如何你测试一下。
关于 GC 之间的区别,是的,我认为我们公司曾经遇到过问题,我们实际上发现控制台应用程序的 GC 与 Web 应用程序的不同。据我所知,Web 应用程序中的 GC 是 运行 服务器模式,但不记得控制台应用程序的 GC 模式。
更多关于 GC 模式的信息:https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/