C# .NET垃圾收集器包含许多静态变量

C# .NET垃圾收集器包含许多静态变量,c#,static,garbage-collection,immutability,C#,Static,Garbage Collection,Immutability,在最近的一个项目中,我发现了许多由静态类持有的公共静态变量。其中一些是字符串,但另一些是名为“Member”的类的实例。总共,我有大约17151个这样的静态实例 问题: 1) 哪些静态实例被认为是GC根?全部或仅成员实例?。我猜字符串将被忽略,因为字符串是不可变的类型,并且不包含对其他类型的引用 2) 你有什么建议?要使“Member”类成为一个结构(它很轻,只有3-4个int或bool类型的字段),或者创建成员的惰性实例?(声明仅在需要时生成成员实例的静态属性)或其他建议。。。我很欣赏任何想法

在最近的一个项目中,我发现了许多由静态类持有的公共静态变量。其中一些是字符串,但另一些是名为“Member”的类的实例。总共,我有大约17151个这样的静态实例

问题: 1) 哪些静态实例被认为是GC根?全部或仅成员实例?。我猜字符串将被忽略,因为字符串是不可变的类型,并且不包含对其他类型的引用

2) 你有什么建议?要使“Member”类成为一个结构(它很轻,只有3-4个int或bool类型的字段),或者创建成员的惰性实例?(声明仅在需要时生成成员实例的静态属性)或其他建议。。。我很欣赏任何想法

由于我将成员设置为beying不可变,并且成员不持有其他对象的实例,是否有可能指示GC停止将这些实例视为beying GC根

谢谢大家!

哪些静态实例被认为是GC根?全部还是全部 成员实例

所有静态成员都被视为GC根

我猜字符串将被忽略,因为它超出了GC根 字符串是不可变类型,不包含对其他字符串的引用 类型

这是不正确的。在类型上声明的静态字符串的根数与其他类型的下一个静态成员的根数相同

你有什么建议


我的建议是首先看看这些实例是否真的给您造成了内存压力。如果是的话,那么我会重新思考为什么首先需要所有这些静态实例?他们都需要在整个生命过程中生活吗?它们可以被缓存吗?他们真的应该是静态成员吗?您可以向自己提出许多问题,以便改进。

感谢您的回答,最重要的是这些成员实例包含一个属性“名称”和一些不太重要的布尔值。“Name”属性是用于与UI层绑定的类属性的名称。这样做是因为beying能够混淆整个代码。创建成员实例时,Name属性使用使用使用表达式树解析的API抓取,因此如果更改属性名称,表达式树也会更新。为什么这些成员实例必须是静态的?您可以使用Observer模式吗?最简单的方法是将它们放在非静态类周围的非静态引用上,并在需要时创建包含这些成员桶的类实例。但这是一项巨大的工作,大约2周的编码/人工。值得吗?@GeorgeLica如果值得还是不值得我们来决定,这可能取决于您的团队领导/项目经理。我们可以说,这些属性似乎不需要是静态的。听起来他们是类实例中的实例成员更合适。@Yuval Itzhakov是的,你说得太对了,最简单的方法就是将他们作为实例类中的实例成员移动。我还看到,其中许多是使用T4模板生成的,因此它比我最初想象的要简单。当成员不持有任何传出引用时,它是否为根并不重要。虽然这肯定是一个很大的问题,但17k小的不可变对象/结构不会成为显示的障碍。不要修复未损坏的。引用类型的所有静态变量都是根。类是否不可变不起任何作用。字符串的一种特殊情况是,当字符串对象在源代码中是一个文本时,它可以作为一个内部字符串启动。它们不是根。一切都无关紧要,GC不是你的问题。修复具有数千个公共静态变量的程序通常需要重写。