如何获取总堆分配?气相色谱。GetAlatedBytesForCurrentThread() 不这样做



我想了解一个线程累计分配了多少内存。从它的文档来看,GC.GetAllocatedBytesForCurrentThread()似乎是一种可以使用的东西,但在实践中,它给了我……其他的东西。

这是我的测试程序,它是使用dotnetcore3.1控制台应用程序VisualStudio模板创建的。

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

阅读没有太多帮助:

https://learn.microsoft.com/dotnet/api/system.reflection.emit.opcodes.newarr

但是,也许数组是由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

因此,在所有情况下,当前线程都不消耗任何东西。

但是,例如,如果您创建了一个List<int>,然后添加了一些项,或者做了任何消耗内存的事情,比如调用medthods(DateTime.Now.ToString()(,线程将消耗内存,您将使用GetAllocatedBytesForCurrentThread方法看到这一点。

但在数组的情况下,如果是CLR线程创建了它们,我们就看不到这一点。

相关内容

  • 没有找到相关文章

最新更新