包含对象实例的静态方法,是不是错了?

时间:2014-10-30 14:45:38

标签: c# garbage-collection static-methods

我正在使用 string 类的扩展方法。在该扩展方法中,我创建了一个StringBuilder实例。

以下是代码:

    public static string GetPlainTextFromHtml(this string htmlString)
    {
        StringBuilder sb = new StringBuilder();
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(htmlString);

        foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//text()"))
        {
            string text = node.InnerText;
            if (!string.IsNullOrEmpty(text))
                sb.Append(text.Trim());
        }

        return sb.ToString();
    }

它有效,但我关心内存管理。 静态方法不会被实例化,所以如果我在静态方法中实例化一个对象会发生什么。让我们说我称这个静态方法100次,内存中是否有100个StringBuilder实例副本?

会导致内存泄漏吗?当静态方法执行终止时,垃圾收集器是否处置对象实例?

4 个答案:

答案 0 :(得分:10)

您的代码完全没有问题。

在静态方法中创建实例的方式与在实例方法中创建实例的方式相同。每次调用都会生成一个新实例,但会超出范围,并在方法调用结束时准备好进行垃圾回收。

我也没有看到任何实现IDisposable的内容,所以你不必担心在那之后清理。

答案 1 :(得分:4)

如果您调用静态方法100次,每次创建StringBuilder时,请执行方法中的工作然后返回。执行并返回该方法后,您的StringBuilder超出范围,并留给垃圾收集器进行清理。所以,是的,如果您调用方法100次,将会有100个StringBuilder创建的实例 - ,但每个实例都会被处理掉并收集垃圾。

答案 2 :(得分:4)

是的,在静态方法中实例化对象是完全可以的。它们位于方法的范围内,即当方法返回时,它们将被标记为垃圾收集(除非您将它们分配给参数的字段或另一个静态字段)。是的,对于方法的每次调用,它都会实例化那些对象,而这正是你想要它做的;否则,多线程这样的方法就是PITA。

如果要回收对象,则需要从保存引用的静态方法访问另一个静态字段。如果您使用多线程,此时您可能会共享资源并需要采取预防措施。

答案 3 :(得分:3)

  

静态方法无法实例化

一般来说,方法不会被实例化,因此实例方法和静态方法之间的垃圾收集没有区别。

您可能想要了解GC works的方法,但简短的回答是 - 此代码中没有内存泄漏 - 一旦GC触发,局部变量将被处置,并且不再可以访问(即在您的示例中,方法执行完成)。