2011-03-28 87 views
2

我有一個DLL項目,使我的應用程序中使用的所有顯示字符串的單。問題是我需要在許多獨立運行的應用程序中引用此DLL。大型數據集 - .NET Framework和C#

我明白,如果我引用的DLL項目中的所有獨立運行的應用程序,他們將所有的DLL加載到內存中,使個別單身人士,他們可以參考,但是這是冗餘我想避免。

有沒有辦法我能保持這種單身的一個實例在內存和各獨立項目中引用呢?

我明白我可能聽起來愚蠢的,這可能裝載根本不發生,但因爲大約一個小時現在:)

我一直在尋找,我使用的C#作爲在.NET框架目標語言。

+1

這可能不是你所需要的,但我建議你看看它:http://en.wikipedia.org/wiki/Global_Assembly_Cache – Kevin 2011-03-28 07:40:51

+0

你也許想看看這個: http:// stackoverflow .com/questions/439787/how-to-implement -explore-memory-in-net – Magnus 2011-03-28 07:44:02

+0

你有多少個應用程序,單個應用程序的字符串消耗多少內存? – mgronber 2011-03-28 07:45:47

回答

2

我不會與內存消耗,直到它是一個真正的問題麻煩嘍。我們可以做一些簡單的計算:2^3(8)個應用程序中的2^13(8192)個字符串是2^16個字符串,如果一個字符串的平均大小爲2^8(256)個字符,則所有字節總數應用程序是2 * 2^24(32 MiB)。即使將字符串的數量乘以10,也不應該產生任何問題。

其他解決方案所需的工作量將使它們在當前階段不可行。如果所有應用程序都使用大多數共享字符串,那麼通用字符串服務也沒有好處。它只有在一小部分字符串真正由他們共享時才提供好處。

隨着遠程處理,你將不得不確保單身實例只在一個地方初始化,你必須通過接口訪問它。很可能你想創建一個本地單例實例,從遠程實例查詢字符串。如果您繼續使用舊的單例實現,直到需要其他解決方案,此解決方案也可以在之後實施。

如果您使用taskmanager來跟蹤內存使用情況,您應該在單例類中有一個非常大的字符串。

public static Strings { 
    private readonly string MemoryUsageTest; 

    static Strings() { 
#if DEBUG 
     int size = 104000000; 
     var text = "abcdefghijklmnopqrstuvwxyz"; 
     var sb = new StringBuilder(size); 

     for (int i = 0; i < size/text.Length; ++i) { 
      sb.Append(text); 
     } 

     MemoryUsageTest = sb.ToString(); 
#endif 
    } 
} 

我不太確定遠程處理在任何時候都是不錯的選擇。無論如何,如果我們假設這將是一個很好的選擇,我會建議當前的實現應該使用實現接口的單例類。這將使遠程實例的使用更容易。

public interface IStrings { 
    string HelloWorld { get; } 
} 

public sealed class LocalStringService : IStrings { 
    internal LocalStringService() { } 

    string IStrings.HelloWorld { 
     get { return "Hello World!"; } 
    } 
} 

public static class StringService { 
    private static readonly IStrings SingletonInstance = new LocalStringService(); 

    // If empty static constructor does not make any sense, read this: 
    // http://csharpindepth.com/Articles/General/Beforefieldinit.aspx 
    static StringService() { } 

    public static IStrings Instance { 
     get { return SingletonInstance; } 
    } 
} 

現在,如果你想使這個偏遠的,你只需要重新命名LocalStringServiceRemoteStringService,使其繼承MarshalByRefObj並改變StringService創建它的遠程實例。另外,RemoteStringService應該在另一個程序集中,以便它不會被其他類加載到內存中。

不過,我懷疑這會給你帶來什麼好處。

+0

你提出的數學是有道理的,我幾乎不能與它爭論。另外,運行這些解決方案的服務器裝有8G內存,所以我現在的問題當然不是阻塞問題。我只是在尋找一種先發制人的解決方案,因此它從一開始就很乾淨。如果事情失控,我現在知道一個解決方案(即遠程處理),但我認爲我會選擇不做任何事情,因爲現在:) – 2011-03-28 12:10:57

+0

如果確實成爲問題,我會推薦C#over .NET遠程 – 2011-04-12 12:18:51

5

一般情況下,不同的工藝有不同的地址空間。由於DLL文件通常被加載到進程地址空間中,因此需要編寫一些特殊的代碼來實現進程之間的數據共享。通常,這是通過Windows API完成的,例如,藉助內存映射文件。您可以瞭解更多關於此在:

Sharing memory between two processes (C, Windows)

使用Windows API是不壞,但它在某種程度上違背了.NET框架的理念。我認爲最好創建一個客戶端 - 服務器架構,當一臺服務器可以使用不同的客戶端並將所需的數據傳遞給它們時。這可以使用例如RemotingWCF來完成。

+0

我同意這個觀點,因爲不同的進程不能直接共享內存。 – Tengiz 2011-03-28 08:14:41

+0

使用了遠程處理並在該塊周圍傳遞了代理副本。謝謝! – 2011-03-28 10:02:26

+1

@Zulfi Tapia:你有沒有保存任何內存?你是否使用了你傳遞過來的對象的接口? – mgronber 2011-03-28 10:21:26

1

使用的字符串常量是最有可能的實習。調用string.IsIntial靜態函數來查看特定的字符串。如果是這樣的話,他們不會佔用過多的內存,因爲每個字符串都在CLR實習生池中。

IsInterned

1

就這個DLL文件的服務的包裝,並調用從其他應用程序服務,而不是。