我正在使用 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实例副本?
会导致内存泄漏吗?当静态方法执行终止时,垃圾收集器是否处置对象实例?
答案 0 :(得分:10)
您的代码完全没有问题。
在静态方法中创建实例的方式与在实例方法中创建实例的方式相同。每次调用都会生成一个新实例,但会超出范围,并在方法调用结束时准备好进行垃圾回收。
我也没有看到任何实现IDisposable
的内容,所以你不必担心在那之后清理。
答案 1 :(得分:4)
如果您调用静态方法100次,每次创建StringBuilder
时,请执行方法中的工作然后返回。执行并返回该方法后,您的StringBuilder
超出范围,并留给垃圾收集器进行清理。所以,是的,如果您调用方法100次,将会有100个StringBuilder
创建的实例 - ,但每个实例都会被处理掉并收集垃圾。
答案 2 :(得分:4)
是的,在静态方法中实例化对象是完全可以的。它们位于方法的范围内,即当方法返回时,它们将被标记为垃圾收集(除非您将它们分配给参数的字段或另一个静态字段)。是的,对于方法的每次调用,它都会实例化那些对象,而这正是你想要它做的;否则,多线程这样的方法就是PITA。
如果要回收对象,则需要从保存引用的静态方法访问另一个静态字段。如果您使用多线程,此时您可能会共享资源并需要采取预防措施。
答案 3 :(得分:3)
静态方法无法实例化
一般来说,方法不会被实例化,因此实例方法和静态方法之间的垃圾收集没有区别。
您可能想要了解GC works的方法,但简短的回答是 - 此代码中没有内存泄漏 - 一旦GC触发,局部变量将被处置,并且不再可以访问(即在您的示例中,方法执行完成)。