C# GC如何清理结构?

C# GC如何清理结构?,c#,.net,C#,.net,我认为GC可能会以不同的方式对待引用类型和值类型 如果没有人对引用类型进行引用,GC将收集该引用类型。 GC何时将收集struct之类的值类型?我的结构不小。我想尽快把它收起来。使用探查器软件,我发现struct的累积量很大,并且是主要的内存消耗量。如果它是实例/静态字段,或者作为另一个对象的一部分,或者被装箱,或者在数组1中,那么struct将仅位于托管堆中(即可以进行垃圾收集的位置)。在托管堆中,它永远不会“赤裸裸”——您可以得到的最接近的值是装箱的值 如果您有一个大型结构,这是您的第一个问

我认为GC可能会以不同的方式对待引用类型和值类型

如果没有人对引用类型进行引用,GC将收集该引用类型。
GC何时将收集struct之类的值类型?我的结构不小。我想尽快把它收起来。使用探查器软件,我发现struct的累积量很大,并且是主要的内存消耗量。

如果它是实例/静态字段,或者作为另一个对象的一部分,或者被装箱,或者在数组1中,那么struct将仅位于托管堆中(即可以进行垃圾收集的位置)。在托管堆中,它永远不会“赤裸裸”——您可以得到的最接近的值是装箱的值

如果您有一个大型结构,这是您的第一个问题。你为什么要创造这样的东西?结构应该几乎总是很小(经验法则通常是32字节),否则每次将其用作方法参数或将其分配给另一个变量时,都会复制它

你考虑过用类来代替吗



正如Eric Lippert喜欢指出的那样。此外,在某些情况下,局部变量最终成为自动生成类中的字段。。。但我认为,这与这个问题有些无关。

如果结构是实例/静态字段,或者是另一个对象的一部分,或者是装箱的,或者是在数组中,那么它只会在托管堆中(即可以进行垃圾收集的位置)。在托管堆中,它永远不会“赤裸裸”——您可以得到的最接近的值是装箱的值

如果您有一个大型结构,这是您的第一个问题。你为什么要创造这样的东西?结构应该几乎总是很小(经验法则通常是32字节),否则每次将其用作方法参数或将其分配给另一个变量时,都会复制它

你考虑过用类来代替吗



正如Eric Lippert喜欢指出的那样。此外,在某些情况下,局部变量最终成为自动生成类中的字段。。。但我认为这与这个问题有些无关。

结构类型是一种值类型,继承自System.ValueType。值类型变量是在当前线程的堆栈(而不是堆)上分配的。未在托管堆上分配内存。它在堆栈上分配,并且在值类型变量超出范围时自动释放。但是,如果要装箱值类型变量,则会在堆上为变量的包装器分配内存,并将变量的字段复制到包装器中。如果您的值类型变量大于85KB,它的包装器将被放置在大对象堆(LOH)中。LOH对象是长期存在的-它们属于Gen2。

结构类型是值类型,从System.ValueType继承。值类型变量是在当前线程的堆栈(而不是堆)上分配的。未在托管堆上分配内存。它在堆栈上分配,并且在值类型变量超出范围时自动释放。但是,如果要装箱值类型变量,则会在堆上为变量的包装器分配内存,并将变量的字段复制到包装器中。如果您的值类型变量大于85KB,它的包装器将被放置在大对象堆(LOH)中。LOH对象是长期存在的-它们属于Gen2。

我们使用struct,因为我们需要通过tcp/ip将struct\data从一台机器发送到另一台机器。@5YrsLaterDBA:这是一个非序列。您可以使用结构或类以各种方式将数据从一台机器发送到另一台机器。您只需要能够以某种方式序列化数据——而且,这里有很多可能性。(二进制序列化、XML、Thrift、协议缓冲区、JSON、YAML,等等…@JonSkeet由于参数复制,我从未意识到存在结构的32字节经验法则。不过,这很有道理。谢谢我们之所以使用struct,是因为我们需要通过tcp/ip将struct\data从一台机器发送到另一台机器。@5YrsLaterDBA:这是一个非序列。您可以使用结构或类以各种方式将数据从一台机器发送到另一台机器。您只需要能够以某种方式序列化数据——而且,这里有很多可能性。(二进制序列化、XML、Thrift、协议缓冲区、JSON、YAML,等等…@JonSkeet由于参数复制,我从未意识到存在结构的32字节经验法则。不过,这很有道理。谢谢