使用阻止进程时管理线程和内存使用情况

时间:2010-06-28 18:50:20

标签: .net multithreading memory-management

我有一堆文件(大约每秒10个)进入系统(存储到数据库中)。每个文件包含1到500个设备之间的条目。给定设备将出现在多个文件中(但不是每个文件)。该数据最终需要存储在每个设备存储的另一个数据库中。有两种不同的文件格式。

有一个API负责最终的数据库部分,它为单个设备提供了几个条目(在幕后,这也会进行一些查找以在数据库中查找ID,因此一次处理多个条目单个设备意味着执行一次查找,而不是每个条目执行一次。

为此,我有一个包含几个部分的程序:

  • 解析文件,将数据提取到一组公共数据对象中。
    • 这是一个线程化进程,每个文件有一个线程,将数据添加到线程安全集合中
    • 在加载每个文件时,其DB条目被标记为“正在进行中”
  • 将对象保存到数据库中
    • 另一个线程进程,它提取给定设备的所有对象,然后告诉数据API保存它们。
    • 从单个文件中保存所有设备成功(或任何失败)后,原始文件的数据库条目将标记为成功/失败

我的问题是:管理何时解析文件,使用多少线程,多少RAM等的最佳方法是什么?

  • 数据API将花费最长时间 - 大部分时间,线程只会等待API返回。
  • 通过为每台设备分组更多数据来提高系统的整体效率
  • 应用程序不应该耗尽RAM,要么解析了这么多文件,但等待保存,导致操作系统交换。
  • 不知道数据库API可以处理多少个同时调用,或者它运行的速度有多快 - 这个过程需要适应那个

那么我怎么知道何时解析文件以确保它尽可能快地运行,而不会因使用太多内存而导致性能下降?

2 个答案:

答案 0 :(得分:1)

看起来你的系统非常受I / O限制(输入端的文件和输出端的DB)。我没有看到任何CPU密集型部件。

显而易见的优化已经存在问题:将大量传入文件捆绑在一起并对每个设备分组数据。成本是Db更新中的内存消耗和延迟。你需要参数。

作为第一个想法,我会将其设置为由有界队列连接的3个块。这些队列将让任何“不堪重负”的组件限制其供应商。

块1:1或2个线程(取决于I / O系统)来读取和解析文件,

块2:1个线程来组织和分组数据。决定何时设备数据应转到Db

块3:1+线程将数据推送到Db。

这些块为这个系统提供了一些灵活性。有限的队列可以让您控制资源消耗。请注意,应该对块2进行参数化以调整块大小。

答案 1 :(得分:0)

我就是这样做的。当每个新文件进入时,将其添加到队列中。让调度员拿起一个文件并开始一个新的线程。

调度程序可以持续监视可用的系统内存和CPU使用情况(例如使用性能计数器api)。

只要有足够的可用内存或足够低的CPU负载,就启动一个新线程。您必须进行一些测试才能找到适合您应用的最佳阈值。

另外,如果你在32位运行,那么一个进程在你出现内存不足之前只能使用大约800mb的ram,所以你可能也需要考虑这个。

开始新工作的第三个因素是DB API。只要它可以吞下您添加的工作,继续添加更多线程。

程序的流程如下:

  1. 使用和解析文件
  2. 达到内存限制(和/或cpu限制)时,将它们批处理到DB API
  3. 在批量处理DB API时,会释放内存,并且可以处理新文件 - goto 1