【问题标题】:Is better to allocate/deallocate an IntPtr (AllocHGlobal) each time or preserve it?每次分配/取消分配 IntPtr (AllocHGlobal) 还是保留它更好?
【发布时间】:2011-01-04 23:29:40
【问题描述】:

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

如果我保留使用 AllocHGlobal 分配的部分内存并在类 Dispose 时释放它会更好,还是应该在每次调用函数时分配/释放?

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

【问题讨论】:

  • @Mitch:堆全局分配不受垃圾收集的影响,因此在内存中不会移动分配的意义上是“固定”的。 (也许内核除外,但 VMM 会透明地处理它。)

标签: c# memory-management intptr


【解决方案1】:

30 秒是永恒的。将 FreeHGlobal 放在 finally 块中以确保它被释放要容易得多。使您不必做终结器和 IDisposable 歌舞。嗯,客户端的代码。

在达到毫秒范围之前,优先考虑缓存而不是堆搅动不会开始得到回报。

【讨论】:

  • (或 sub-毫秒范围。)
  • 他说的是“30 秒”还是“每秒 30 次”?即使是后者,这些天也有足够的时间做很多事情,但它确实开始证明优化考虑在 30 秒的情况下完全没有意义。
【解决方案2】:

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

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

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

【讨论】:

  • 谢谢,顺便说一句,我认为代码已经很干净了(我写的很聪明,我的库在第一次尝试时就工作了,没有任何错误......我真的很高兴,首先它发生的时间:P)。多线程问题...我应该考虑一下这个
【解决方案3】:

您可以这样做,只要:

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

但是,P/Invoke 调用的实际封送处理更有可能成为瓶颈。您是否已经真正分析过代码,或者您是否在进行微优化?

【讨论】:

  • 实际上代码运行良好,但我没有测试高消耗工作,我只是在防止问题......我会测试。 编辑:该死,我浪费了 很多 (300MB) 内存,但我认为问题是由于位图克隆造成的,请稍等以进行另一次测试
  • 已解决,我在部分代码中做了很多垃圾。我优化了它,现在不浪费一个字节(我总是用 WinForm 大约 28 MB,我认为这很好),顺便保留 AllocHGlobal
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 2013-01-02
  • 1970-01-01
  • 2013-04-03
  • 2019-08-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多