【问题标题】:Improving .Net memory speed and efficiency [closed]提高.Net内存速度和效率[关闭]
【发布时间】:2013-03-27 22:22:34
【问题描述】:

我有一项服务,我在很长一段时间内查询一次,我想“简化”或提高其内存分配的效率。

大多数时候它只是坐着等待,偶尔它会收到一个需要分配很多内存的请求,并对其进行一些处理。我事先不知道类型或结构 - 这取决于请求,并且变化很大。

现在,大型处理请求被一些喋喋不休(其他请求)排除,这可能需要几秒钟。

我想要做的是,当聊天(较小的请求)开始时,对 .Net 框架说:转到 Windows,并为自己获取几 GB 的内存,以便在我询问时更快地可用,当我完成后,对 .Net 说:我目前没有使用的所有东西,你可以还给我,因为我暂时不需要它。


在我们说话的时候,我正在开始分析...但我怀疑这将是可以改进的问题的一部分。

我会尽量澄清情况。

我有一个位于服务器上的服务,95% 的时间什么都不做。每隔一段时间,它就会收到执行一些主要是内存密集型处理的请求。

我提前一点时间就知道这一切都会发生。

我想要做的只是提示 GC“很快就会需要大量内存”,然后是“暂时不需要任何特别的东西”


好的。 我已经完成了分析,并决定我不在乎这个。 分配确实需要一些时间(几到几十毫秒),但与处理的其余部分相比,它是微不足道的......

关于发布部分,它最终会发生,并且不会真正干扰服务器的其余部分......

【问题讨论】:

  • 您的意思是突发的内存分配会导致您的应用程序出现可衡量的性能问题吗?否则,你怎么知道堆管理器和垃圾收集器并没有完全按照你的要求做?
  • 您将无法优化框架的垃圾/内存管理。它已经非常好......此外,由于问题非常模糊,因此很难就您当前的情况提供任何建议。
  • 而你怎么知道瓶颈是内存分配?
  • 分配内存非常快(只要你有足够的空闲空间)。我很有信心这不是你的瓶颈。
  • @AK_ 我说没关系。分配内存不依赖于分配的内存量。分配一个字节并不比分配 100 MB 快。

标签: c# .net memory-management garbage-collection


【解决方案1】:

GC 大部分时间都足够聪明,可以为您执行此操作。但是,这是一个架构问题,可以通过修改服务中的活动流来解决。

例如您可以在请求到来之前提前分配处理大请求所需的对象。但是,对于解除分配,要么显式地为它们实现 idisposible 接口,并在它们被使用后销毁它们,要么将其留给 GC。

此外,您必须了解内存分配的工作原理。为了获得为 .Net 对象分配的内存,您必须提前知道对象的类型。仅仅分配一块普通的内存对你没有任何帮助。大多数情况下,与框架用于为对象分配内存的 malloc 相比,对象创建或克隆代码更消耗资源。

考虑到细节,我想说的是,即使您可以成功地执行此例程,它也会变得更加复杂,并且可能会在您的代码中添加更多错误。最好把它留给 .Net 框架。它非常擅长分配和释放内存。

【讨论】:

  • 我大部分时间都喜欢 GC :-)。问题是,它需要执行 malloc 的 很多 内存。我只是希望它提前一点做 malloc,并尽快免费。
  • @AK_ 分配内存很便宜;对 GC 来说,这是昂贵的释放,所以尝试这样做并不会真正帮助您。很有可能你最终会变得更糟,试图自己管理它。
  • 不想自己管理它,虽然我知道我可以,但工作量太大。正如我所说,我只是想提示 GC 如何做得更好,如果可能的话......
  • @AK_ 1) 这不可能,因为有几个人已经告诉过你 2) 它仍然没有任何帮助。
【解决方案2】:

如果您希望能够保留一块内存供您使用,请参阅:

allocating "unmanaged" memory in c#

注意,这样做可能会有风险,而且 .NET VM 中的垃圾收集器和内存分配已经相当不错了。

如果内存分配可以在很大程度上被缓存,那么我建议缓存可以使用WeakReference 执行的操作,以便快速连续请求可以从访问缓存数据中受益,但是如果垃圾收集在间隔为相隔相当多的数据,然后可以发布数据并在下一个请求中重新创建。

见:Weak reference benefits

还有:http://msdn.microsoft.com/en-gb/library/system.weakreference.aspx

【讨论】:

  • 1.我不需要非托管内存,也不想自己开始将其分配到对象中。 2.缓存对我没有帮助,我实际上正在寻找相反的东西,处理完成后我不再需要那些数据......
  • @AK_ 然后除了调用GC.Collect() 之外,您无能为力,Collect 会通知垃圾收集器您想要清理一些内存,但这完全取决于何时和它决定做多少。
  • 从我目前看到的情况来看,GC.Collect() 大多不理我...
  • @AK_ aha 是的,它通常会以这种方式出现,它只是向 GC 暗示它可能想要进来并清理,但如果它认为不是这样,你就不会获取您想要的收藏。原因如下:stackoverflow.com/questions/11354086/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 2012-08-22
  • 2015-03-21
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多