让我们举一个例子,我认为这个例子涵盖了我的所有问题:
class SomeClass
{
static SomeType PropertyA
{
get
{
if (....)
return MethodA();
else
return MethodB();
}
}
static SomeType MethodA() { ... }
static SomeType MethodB() { ... }
}
会调用SomeClass.PropertyA属性创建内存泄漏吗?我的意见是否定的,因为该属性本身没有支持字段,这会产生内存泄漏。我问这个是因为我已经读过静态属性可以创建内存泄漏,但我认为它是负责内存泄漏的支持字段,因为它保存了对实例的引用。
因此,在上面的示例中,上面示例中的MethodA,MethodB和PropertyA不应该创建任何内存泄漏。我错了吗?
我的另一个问题是:我有很多类,大多数没有状态和数据。他们只是作为代理。其中一些方法被频繁调用。我的问题是:我应该将这些类设为单例,静态或常规类吗?
完美的例子是一个包含5-10个方法的类,并执行一些SQL查询。
1)如果我将它们作为常规,那么我需要经常创建它们(在一些用户反应中),调用一些方法,然后允许垃圾收集。
2)在单身和静态之间做出选择,利弊是什么?
3)如果我有一个包含代理方法的类,但有2-3个IDbCommands,每个包含10个参数,并且有利于重用它们,那么在选择正确的模式时会改变什么吗?
编辑:因为我得到了一些让我更加困惑的答案,可能是由于误解,我将在第一个问题上回答。我做了一个测试,在那里我分配了一个大字节数组(300MB),通过PropertyA(和MethodA)检索。 以上示例中的PropertyA abd MethodA在获取之后都不会保存对此对象的引用,因此只要使用数组调用代码,它就会由GC处理。因此,如果我们只使用静态属性和静态方法,那么不应该有任何内存泄漏。
答案 0 :(得分:1)
因此,在上面的示例中,上面示例中的MethodA,MethodB和PropertyA不应该创建任何内存泄漏。我错了吗?
如果你的意思是他们不会创造或保留任何记忆,那就是真的 - 财产本身不会占有记忆。
静态字段不会产生“内存泄漏” - 类型的类型初始值设定项将在第一次使用类之前运行,如果字段需要内存,则将分配该字段的内存。这个内存没有被清除 - 如果你的意思是“泄漏” - 但是没有实例可以释放,所以这是预期和期望的行为。
答案 1 :(得分:0)
简单的答案是一个问题:“这些方法做了什么,做了什么状态,除了简单的垃圾收集之外,它们是否需要进行清理?”
如果他们不满足以上所有要求,那么您就不会有泄漏。如果您没有对此采取任何措施,则只会发生泄漏,如果您没有任何操作,则需要执行任何不泄漏的操作。
这些天更多的是关于“记忆压力”而不是泄漏。
一般情况下,我倾向于实例方法,因为它提供了垃圾收集,并允许更容易地模拟和测试场景。
静态方法和变量与实例变量和方法存在相同的问题,因此泄漏(如果可能)适用于两者。