2014-10-30 70 views
8

我使用扩展方法字符串类。在该扩展方法中,我创建了一个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实例的副本?

会造成内存泄漏吗?垃圾收集器在静态方法执行终止时配置对象实例吗?

+1

'静态方法不被实例化'非静态方法也没有被实例化。类实例只包含数据。方法被称为(未实例化)。区别在于非静态方法是通过类实例调用的,而静态方法是不带类实例的。 – 2014-10-30 14:55:31

回答

4

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

4

是的,完全可以在静态方法中实例化对象。他们生活在方法的范围内,即当方法返回时,它们将被标记为垃圾收集(除非将它们分配给参数的字段或另一个静态字段)。是的,每次调用该方法时,都会实例化这些对象,而这正是您希望它执行的操作;否则,多线程这种方法将是一个PITA。

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

10

你的代码绝对没有错。

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

我也没有看到任何实现IDisposable的东西,所以你不需要担心自己在那里清理。

+0

我可以在静态方法内创建对象实例。但我正在阅读[this](https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members)microsoft文档它说我们不能:静态方法和属性不能访问它们包含的类型中的非静态字段和事件,除非它明确地传入方法参数,否则它们不能访问任何对象的实例变量。 “这句话的意思是什么? – stom 2017-07-18 06:46:09

3

静态方法不能被实例一般

方法没有得到实例化,所以有一个实例方法的一个静态之间的垃圾收集没有区别。

您可能想要了解GC works,但一个简短的答案是 - 不存在此代码中的内存泄漏 - 一旦GC启动并且无法再访问这些局部变量,则会丢弃局部变量(即在您的示例中,方法执行结束)。

相关问题