2011-03-28 42 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文件的服务的包装,并调用从其他应用程序服务,而不是。