2014-10-30 73 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啓動並且無法再訪問這些局部變量,則會丟棄局部變量(即在您的示例中,方法執行結束)。

相關問題