C# 如何获得总堆分配?GC.GetAllocatedBytesForCurrentThread()不';我做不到
我想知道一个线程累计分配了多少内存。从它的文档来看,C# 如何获得总堆分配?GC.GetAllocatedBytesForCurrentThread()不';我做不到,c#,.net-core,garbage-collection,C#,.net Core,Garbage Collection,我想知道一个线程累计分配了多少内存。从它的文档来看,GC.GetAllocatedBytesForCurrentThread()似乎是要使用的东西,但实际上,它给了我。。。还有别的 这是我的测试程序,使用dotnet core 3.1控制台应用程序Visual Studio模板创建 using System; class Program { static void Main() { long start, difference; start = GC.
GC.GetAllocatedBytesForCurrentThread()
似乎是要使用的东西,但实际上,它给了我。。。还有别的
这是我的测试程序,使用dotnet core 3.1控制台应用程序Visual Studio模板创建
using System;
class Program {
static void Main() {
long start, difference;
start = GC.GetAllocatedBytesForCurrentThread();
var x = new int[1_000_000];
difference = GC.GetAllocatedBytesForCurrentThread() - start;
Console.WriteLine("{0} bytes allocated for array construction", difference);
start = GC.GetAllocatedBytesForCurrentThread();
Console.WriteLine(DateTime.Now.ToString());
difference = GC.GetAllocatedBytesForCurrentThread() - start;
Console.WriteLine("{0} bytes allocated for date printing", difference);
}
}
它给了我这个输出
0 bytes allocated for array construction
9/17/2020 11:26:40 AM
19040 bytes allocated for date printing
Press any key to continue . . .
我不相信不在堆上分配一个字节就可以创建一百万个元素的数组
那么,有没有一种方法可以跟踪线程的堆分配?这个方法到底在做什么,如果有的话
这里有一个更长、更全面的测试程序,包括到目前为止的所有建议。我包含了sum部分,以验证在代码运行时是否确实创建了数组
using System;
using System.Linq;
class Program {
static void Main() {
long start, difference;
{
start = GC.GetAllocatedBytesForCurrentThread();
var x = new int[1_000_000];
x[^1] = 7;
difference = GC.GetAllocatedBytesForCurrentThread() - start;
Console.WriteLine("{0} bytes thread allocated for array construction (sum: {1})", difference, x.Sum());
}
start = GC.GetAllocatedBytesForCurrentThread();
Console.WriteLine(DateTime.Now.ToString());
difference = GC.GetAllocatedBytesForCurrentThread() - start;
Console.WriteLine("{0} bytes thread allocated for date printing", difference);
{
start = GC.GetTotalMemory(true);
var x = new int[1_000_000];
x[^1] = 7;
difference = GC.GetTotalMemory(true) - start;
Console.WriteLine("{0} bytes total allocated for array construction (sum: {1})", difference, x.Sum());
}
start = GC.GetTotalMemory(true);
Console.WriteLine(DateTime.Now.ToString());
difference = GC.GetTotalMemory(true) - start;
Console.WriteLine("{0} bytes total allocated for date printing", difference);
}
}
输出:
0 bytes thread allocated for array construction (sum: 7)
9/17/2020 11:51:54 AM
19296 bytes thread allocated for date printing
4000024 bytes total allocated for array construction (sum: 7)
9/17/2020 11:51:54 AM
64 bytes total allocated for date printing
通过以下IL代码进行阵列分配:
// int[] array = new int[1000000];
IL_0008: ldc.i4 1000000
IL_000d: newarr [mscorlib]System.Int32
IL_0012: stloc.2
阅读没有提供很多帮助的内容:
但可能数组是由CLR中的另一个线程创建的,事实上是由CLR线程本身创建的,我认为这就是为什么GC.GetAllocatedBytesForCurrentThread()-start
返回0
,而使用GetTotalMemory
返回正确和真实的数量
数组在堆中分配,而本地值类型和引用直接在方法堆栈中创建
例如:
.locals init (
[0] int64 'value'
)
IL_0001: ldc.i4.s 10
IL_0003: conv.i8
IL_0004: stloc.0
因此,在所有情况下,当前线程都不会消耗任何东西
但是,例如,如果您创建一个列表
,然后添加一些项目,或者执行任何消耗内存的操作,比如调用medthods(DateTime.Now.ToString()
),线程将消耗内存,您将看到使用GetAllocatedBytesForCurrentThread
方法
但是在数组的情况下,如果是CLR线程创建了它们,我们看不到这一点。如果使用
GC.GetTotalMemory(true)
而不是方法,会得到什么?我在.NET4.7.2(VS2017)上获得了约4MB的内存。这给了我更合理的数字,但似乎还包括其他线程。这个最小复制没有任何其他线程,但如果可能的话,我想在不那么琐碎的场景中使用此技术。我无法在我的计算机上进行测试,但您是否尝试更改一些单元格,因为这里您对数组不做任何操作。。。也许这就是GetAllocatedBytesForCurrentThread看到0的原因。@OlivierRogier既不接触数组,也不将数组馈送给GC。KeepAlive
做任何事情。分配一个容量为1m的列表
需要32个字节。我想知道如果您这样做会发生什么?