![](/img/trans.png)
[英]how GetAllocatedBytesForCurrentThread() works? how to get used memory by a thread?
[英]How can I get total heap allocations? GC.GetAllocatedBytesForCurrentThread() doesn't do it
我想知道一个线程累计分配了多少内存。 从它的文档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
没有提供太多帮助的阅读:
https://docs.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 线程,我们就看不到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.