1

让我们举个例子,我认为它涵盖了我所有的问题:

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 处理。因此,如果我们仅将静态属性与 getter 或静态方法一起使用,则不应存在任何内存泄漏。

4

2 回答 2

1

所以在上面的例子中,上面例子中的 MethodA、MethodB 和 PropertyA 不应该造成任何内存泄漏。我错了吗?

如果您的意思是它们不会创建或保留任何内存,那么这是真的 - 属性本身不会保留内存。

静态字段不会造成“内存泄漏”——该类型的类型初始化程序将在第一次使用该类之前运行,并且,如果一个字段需要内存,将分配该字段的内存。这个内存没有被清除——如果这就是你所说的“泄漏”——但没有实例可以释放,所以这是预期和期望的行为。

于 2012-08-25T01:23:24.820 回答
0

简单的答案是一个问题:“这些方法做了什么,它们是否保持状态,除了简单的垃圾收集之外,它们是否需要清理?”

如果他们不满足以上所有要求,那么按理说你不会有泄漏。仅当您不采取任何措施并且您不采取任何措施时,才会发生泄漏,您就没有泄漏。

如今,它更多的是关于“内存压力”而不是泄漏。

一般来说,我更喜欢实例方法,因为它提供垃圾收集并允许更容易地模拟和测试场景。

静态方法和变量与实例变量和方法存在相同的问题,因此泄漏(如果可能)适用于两者。

于 2012-08-25T01:30:10.997 回答