我有一个Windows控制台应用程序应该运行几天和几个月没有重新启动.该应用程序从MSMQ检索"工作"并进行处理.有30个线程同时处理工作块.
来自MSMQ的每个工作块大约为200kb,其中大部分分配在单个String对象中.
我注意到,在处理了大约3-4千个这些工作块之后,应用程序的内存消耗非常高,消耗了1到1.5 GB的内存.
我通过分析器运行应用程序并注意到大部分内存(可能是一个演出)在大对象堆中未使用但结构是分段的.
我发现这些未使用的(垃圾收集)字节中有90%是先前分配的字符串.我开始怀疑从MSMQ进来的字符串是分配,使用然后解除分配,因此是碎片的原因.
我明白像GC.Collect(2或GC.Max ...)这样的东西不会有用,因为它们是gc大对象堆但不压缩它(这是问题).所以我认为我需要的是缓存这些字符串并以某种方式重用它们,但由于字符串是不可变的,我将不得不使用StringBuilders.
我的问题是:无论如何都没有改变底层结构(即使用MSMQ,因为这是我无法改变的),并且仍然避免每次初始化一个新的String以避免分裂LOH?
谢谢,Yannis
更新:关于如何检索这些"工作"块
目前,它们作为WorkChunk对象存储在MSMQ中.这些对象中的每一个都包含一个名为Contents的String和另一个名为Headers的String.这些是实际的文本数据.如果需要,我可以将存储结构更改为其他内容,如果需要,我可以将基础存储机制更改为MSMQ以外的其他内容.
目前我们在工作节点方面
WorkChunk chunk = _Queue.Receive();
所以在这个阶段我们几乎无法缓存.如果我们以某种方式改变了结构,那么我想我们可以做一些进步.无论如何,我们必须解决这个问题,以便我们做任何需要做的事情,以避免浪费数月的工作.
更新:我继续尝试下面的一些建议,并注意到这个问题无法在我的本地计算机上运行(运行Windows 7 x64和64位应用程序).这使事情变得更加困难 - 如果有人知道为什么那么它真的有助于在本地重新调整这个问题.
.Net 4.0中是否提供Server GC(配置中的gcServer标志)?或者它被弃用了?
谢谢!!!