C# 每次分配/取消分配IntPtr(AllocHGlobal)还是保留它更好?

C# 每次分配/取消分配IntPtr(AllocHGlobal)还是保留它更好?,c#,memory-management,intptr,C#,Memory Management,Intptr,在我调用FreeHGlobal的函数结束时,我经常在一个函数上使用AllocHGlobal(大小总是相同的)(可能每秒30次) 如果我保持用AllocHGlobal分配的内存部分,并在类Dispose时释放它,或者每次调用函数时我都应该alloc/free,这会更好吗 我不知道这种记忆在c#中是如何表现的,它对我来说是一个“新世界”你可以这样做,只要: 所需的内存量始终小于或等于分配的大小。(您已经指出情况是这样的。) 一次不会从多个线程调用该方法 该方法不是可重入的 当不再需要内存时,请小心

在我调用FreeHGlobal的函数结束时,我经常在一个函数上使用AllocHGlobal(大小总是相同的)(可能每秒30次)

如果我保持用AllocHGlobal分配的内存部分,并在类Dispose时释放它,或者每次调用函数时我都应该alloc/free,这会更好吗


我不知道这种记忆在c#中是如何表现的,它对我来说是一个“新世界”

你可以这样做,只要:

  • 所需的内存量始终小于或等于分配的大小。(您已经指出情况是这样的。)
  • 一次不会从多个线程调用该方法
  • 该方法不是可重入的
  • 当不再需要内存时,请小心地释放内存。(换句话说,如果指针保存在非静态类字段上,则类应实现
    IDisposable
    ,并且
    Dispose()
    方法应释放内存。当然,类使用者必须调用
    Dispose()
    或使用
    using(){}
    块。)

然而,p/Invoke调用的实际封送很可能成为瓶颈。你真的分析过代码了吗,还是在进行微优化?

30秒是永恒的。将FreeHGlobal放在finally块中以确保其发布要容易得多。使您无需进行终结器和可识别的歌曲和舞蹈。客户的代码


支持缓存而不是堆搅动直到达到毫秒范围才开始有回报。

与任何性能问题一样,首先编写干净的代码,测量并优化所需的内容

如果您非常确定您的对象永远不会被多个线程使用(从而同时调用所讨论的函数),那么缓存分配的内存似乎很好


如果您决定缓存依赖于垃圾收集的未管理内存块,则可能不足以提前释放内存。未管理内存(AllocHGlobal)不计入CLR分配的内存,因此可能会延迟对象的垃圾收集)。您应该在对象上实现并适当地使用IDisposable。

@Mitch:Heap全局分配不受垃圾收集的约束,因此在内存中没有任何东西会移动分配的意义上是“固定”的。(除了内核,但VMM将透明地处理这个问题。)(或亚毫秒范围。)他说了“30秒”或“每秒30次”吗?即使是后者现在也足够做很多事情了,但它确实开始证明优化考虑是完全没有意义的,在30秒的时间内。实际上代码工作得很好,但我没有测试高消耗的工作,我只是在防止问题。。。我来测试一下。编辑:该死,我浪费了很多(300MB)的内存,但我认为问题是由于位图克隆造成的,请稍等片刻,等待另一个测试解决,我在部分代码中做了大量的垃圾处理。我对它进行了优化,现在没有浪费一个字节(我用WinForm总是在28MB左右,我认为这很好),不得不顺便保留AllocHGlobal。谢谢,顺便说一下,我认为代码已经很干净了(我以一种非常聪明的方式编写,我的库在第一次尝试时就工作了,没有任何错误……我真的很高兴,第一次出现:P)。多线程问题。。。我应该考虑一下