C# 中的每线程内存管理

发布于 2024-09-03 01:03:31 字数 449 浏览 1 评论 0 原文

继续了解 VS2010 C# 并行分析结果中的讨论,但更重要的是:

我有许多并行工作的线程(使用 Parallel.For/Each),它们为小类使用许多内存分配。

这会在全局内存分配器线程上产生争用。

有没有办法指示 .NET 为每个线程预分配内存池并从该池中进行所有分配?

目前我的解决方案是我自己的内存池实现(全局分配的 T 类型对象数组,它们在线程之间回收),这有很大帮助,但效率不高,因为:

  1. 我无法指示 .NET 从特定内存进行分配片。
  2. 我仍然需要多次调用new来为池分配内存。

谢谢,
哈该

Continuing the discussion from Understanding VS2010 C# parallel profiling results but more to the point:

I have many threads that work in parallel (using Parallel.For/Each), which use many memory allocations for small classes.

This creates a contention on the global memory allocator thread.

Is there a way to instruct .NET to preallocate a memory pool for each thread and do all allocations from this pool?

Currently my solution is my own implementation of memory pools (globally allocated arrays of object of type T, which are recycled among the threads) which helps a lot but is not efficient because:

  1. I can't instruct .NET to allocate from a specific memory slice.
  2. I still need to call new many times to allocate the memory for the pools.

Thanks,
Haggai

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

动听の歌 2024-09-10 01:03:31

我搜索了两天试图找到与您遇到的同一问题的答案。答案是你需要将垃圾收集模式设置为Server模式。默认情况下,垃圾收集模式设置为工作站模式。
将垃圾收集设置为服务器模式会导致托管堆分为单独管理的部分,每个 CPU 一个。
为此,您需要将配置设置添加到 app.config 文件中。

<runtime>
   <gcServer enabled="true"/>
</runtime>

我的 12 核 Opteron 6172 上的速度差异非常惊人!

I searched for two days trying to find an answer to the same issue you had. The answer is you need to set the garbage collection mode to Server mode. By default, garbage collection mode set to Workstation mode.
Setting garbage collection to Server mode causes the managed heap to split into separately managed sections, one-per CPU.
To do this, you need to add a config setting to your app.config file.

<runtime>
   <gcServer enabled="true"/>
</runtime>

The speed difference on my 12-core Opteron 6172 was dramatic!

浪漫之都 2024-09-10 01:03:31

垃圾收集器不分配内存。

听起来更像是您分配了大量小型临时对象和一些长期存在的对象,并且垃圾收集器花费了大量时间对临时对象进行垃圾收集,因此您的应用程序不必从操作系统。来自 .NET Framework 4 高级开发 - 垃圾收集

只要托管堆中的地址空间可用,运行时就会继续为新对象分配空间。然而,记忆并不是无限的。最终垃圾收集器必须执行收集才能释放一些内存。

解决方案:不要分配大量小型临时对象。垃圾收集和性能也可能有帮助。

The garbage collector does not allocate memory.

It sounds more like you're allocating lots of small temporary objects and a few long-lived objects, and the garbage collector is spending a lot of time garbage-collecting the temporary objects so your app doesn't have to request more memory from the OS. From .NET Framework 4 Advanced Development - Garbage Collection:

As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory.

The solution: Don't allocate lots of small temporary objects. The page on Garbage Collection and Performance might also be helpful.

じ违心 2024-09-10 01:03:31

您可以预先分配一堆对象,并将它们保存在用于单独线程的组中。但是,您可能不会从中获得任何更好的性能。

垃圾收集器是专门为高效处理小型短命对象而设计的。如果将对象保留在池中,它们将是长期存在的,并且将在垃圾收集中幸存下来,这反过来意味着它们将被复制到第二代堆中。这种复制比仅仅分配新对象的成本更高。

You could pre-allocate a bunch of objects, and keep them in groups intended for separate threads. However, it's likely that you won't get any better performance from this.

The garbage collector is specially designed to handle small short-lived objects efficiently. If you keep the objects in a pool, they are long-lived and will survive a garbage collection, which in turns means that they will be copied to the second generation heap. This copying will be more expensive than just allocating new objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文