2

我正在尝试修复一个非常大的应用程序中的内存峰值。虽然我不确定这会对记忆产生多大影响,但我注意到以下几点:

  • 应用程序使用自定义线程池来完成所有昂贵的任务
  • 应用程序将执行所有传入的任务
  • 任务可以由数千个子任务组成
  • 虽然线程池一次只会执行 {T} 个任务,并在开始新任务之前完全完成一个任务,但它确实会创建一个新的系统线程(线程类)并为添加到其中的每个子任务启动它
  • 子任务系统线程以线程启动方式启动,该线程启动会立即阻塞手动重置事件 (MRE),等待线程池插槽释放

因此,这个线程池可以创建数千个线程,但是在其他任务完成时,除了 30 个(或您配置的任何内容)之外的所有线程都将在 MRE 上被阻塞。

我的问题:


在 MRE 上阻塞的一千个线程会对内存/处理器产生什么影响?我没有太多时间来修复这个峰值,所以如果它是最小的,我宁愿留下这个问题,并在我有更多时间的时候在以后的补丁中修复它。

此外,这种行为在线程池中是典型的,还是听起来有缺陷(我倾向于有缺陷,但我没有足够好的背景来确定)。

4

1 回答 1

3

在 MRE 上阻塞的一千个线程会对内存/处理器产生什么影响?我没有太多时间来修复这个峰值,所以如果它是最小的,我宁愿留下这个问题,并在我有更多时间的时候在以后的补丁中修复它。

每个线程在手动创建时都有自己的堆栈分配给它。默认情况下,这将是每个线程 1MB,尽管可以通过构造函数参数使线程具有更小的堆栈

你最好重新设计这个,从你的问题的描述,使用标准的 ThreadPool 和一个喜欢BlockingCollection<T>处理你的节流的类。这旨在直接允许边界输入,并带有阻塞。与使用框架中包含的高度调整的 ThreadPool 相比,制作无限数量的线程的自定义“线程池”效率要低得多。

此外,这种行为在线程池中是典型的,还是听起来有缺陷(我倾向于有缺陷,但我没有足够好的背景来确定)。

这绝对是有缺陷的。ThreadPool 的全部意义在于避免为每个请求创建一个线程,并为多个请求“池化”线程(重用它们)而无需重新创建它们。

于 2013-03-07T17:38:49.183 回答