有人编写或知道用C#编写的自定义内存管理器吗?

4
我们有一款用C#编写的应用程序,希望它保持原样。该应用程序操作许多小而短暂的动态内存块。同时,它似乎对GC中断很敏感。
我们认为减少GC的一种方法是分配100K的块,然后使用自定义内存管理器从中分配内存。有没有人在C#中遇到过自定义内存管理器实现?

5
我认为大多数C#应用程序操作许多小的、短暂的动态内存块。你的应用程序有什么特别之处? - MusiGenesis
13
如果你的应用对GC中断非常敏感,就不要使用GCed语言编写它。不要与语言作斗争,选择正确的语言。 - Craig Gidney
该应用程序是从Python移植而来的,Python也是一种带有垃圾回收机制的语言。Python版本对于垃圾回收中断并不那么敏感。 - mark
1
仅澄清一下,严格来说,GC 不属于语言本身,而是运行时环境(虚拟机)的一部分。理想情况下,会有第三方虚拟机,例如针对实时环境的确定性 GC 方案。 - redcalx
你可以研究一下Mono项目。他们不得不编写自己的内存管理器,以便他们的框架可以在Linux上运行。 - Dan Herbert
5个回答

8

但是您可能目前并未使用结构体,因为您需要继承... 如果是这种情况,该模型可能非常难以实现(根据我的经验 - 因此找到了forceLayout设置runtime.interop iirc)。 - John Nicholas
1
池化是一个很好的选择模式,但通常池本身并不需要:只需分配一个对象并重复使用它(例如:任何System.Security.Cryptography.HashAlgorithm子类之一)。 - rpetrich

4
所有继承自 System.Object 的类型的内存管理都由垃圾回收器执行(除了存储在堆栈上的结构/基元)。在微软CLR的实现中,垃圾回收器无法被替换。
您可以在不安全块中手动分配一些基元到堆中,然后通过指针访问它们,但这并不推荐。
通常,您应该对类进行性能分析,并相应地将其迁移到结构中。

+1 用于将类迁移到结构体。 如果需要结构继承,请考虑使用 forceOverride 设置……它很邪恶,但可以完成工作,而且速度快。 - John Nicholas
你能告诉我哪里可以找到“forceOverride settings”吗?这可能会很有用。 - rpetrich

3

显然的选择是使用Marshal.AllocHGlobalMarshal.FreeHGlobal。我还有一份在C#中编写并经过实战检验的DougLeaAllocatordlmalloc)副本。如果您愿意,我可以把它拿出来给您。无论哪种方式都需要仔细、一致地使用IDisposable


DougLeaAllocator听起来很有趣。我想要一份拷贝。是否有一个可以下载/阅读C#版本的网站?我的电子邮件是mark点kharitonov在gmail上。谢谢。 - mark

1

垃圾回收只有在对象没有引用时才会收集项目。

您应该创建一个静态类或其他东西,以保持应用程序生命周期内的对象的生存期引用。

如果您想管理自己的内存,可以在C#中使用不安全代码,但最好选择像C++这样的非托管语言。


0
尽管我没有经验,但你可以尝试编写C#非托管代码。或者,你可以通过调用GC来告诉它不要收集你的对象。
GC.KeepAlive(obj);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接