memory - 跨线程协作内存使用?

标签 memory multithreading memory-management

我有一个应用程序,它有多个线程处理待办事项队列中的工作。我对进入队列的内容和顺序没有影响(它由用户从外部提供)。队列中的单个工作项可能需要几秒钟到几个小时的运行时间,并且在处理时不应中断。此外,单个工作项可能会消耗几兆字节到大约 2GB 的内存。内存消耗是我的问题。我在 8GB 机器上作为 64 位进程运行,有 8 个并行线程。如果他们每个人同时遇到最坏情况的工作项目,我就会耗尽内存。我想知道解决这个问题的最佳方法。

  1. 保守计划并仅运行 4 个线程。最坏的情况应该不再是问题,但我们浪费了很多并行性,使得平均情况变慢了很多。
  2. 在开始新项目之前,让每个线程检查可用内存(或者更确切地说是所有线程分配的总内存)。仅当剩余内存超过 2GB 时才启动。定期重新检查,希望其他线程能够完成它们对内存的占用,我们最终可以开始。
  3. 尝试预测队列中需要多少内存项(困难)并进行相应的计划。我们可以重新排序队列(覆盖用户选择)或简单地调整正在运行的工作线程的数量。
  4. 还有更多想法吗?

我目前倾向于第二种,因为它似乎很容易实现和解决大多数情况。但是,我仍然想知道处理这种情况的标准方法是什么?毕竟,操作系统必须在进程级别上执行非常相似的操作...

问候,

Sören

最佳答案

所以您当前最坏情况的内存使用量是 16GB。只有 8GB 的​​ RAM,在操作系统和系统进程占用其份额后还剩下 6 或 7GB 就很幸运了。因此,平均而言,在中等负载的系统上,您已经会消耗内存。机器有多少个核心?因为是8核机器所以有8个工作线程吗?

基本上,您可以减少内存消耗,或增加可用内存。您的选项 1(仅运行 4 个线程)未充分利用 CPU 资源,这可能会使吞吐量减半 - 绝对不是最佳选择。

选项 2 是可行的,但有风险。内存管理非常复杂,查询可用内存并不能保证您能够继续分配该内存量(不会导致分页)。磁盘 I/O 突发可能导致系统增加缓存大小、后台进程可能启动并交换其工作集以及许多其他因素。由于这些原因,可用内存越小,您对它的依赖就越少。此外,随着时间的推移,内存碎片也会导致问题。

选项 3 很有趣,但很容易导致 CPU 负载不足。如果您运行的作业具有较高的内存要求,您最终可能只运行几个线程,并且处于与选项 1 相同的情况,即核心负载不足。

那么采取“减少消耗”的策略,你真的需要一次性将整个数据集存入内存吗?根据算法和数据访问模式(例如随机与顺序),您可以逐步加载数据。更深奥的方法可能涉及压缩,具体取决于您的数据和算法(但实际上,这可能是浪费精力)。

然后是“增加可用内存”。就性价比而言,您应该认真考虑购买更多内存。有时,为了达到相同的最终结果,投资更多的硬件比开发时间更便宜。例如,您可以花费几百美元安装 32GB RAM,这将立即提高性能,而不会增加解决方案的任何复杂性。随着性能压力的减轻,您可以分析应用程序,看看可以在哪些方面提高软件的效率。

关于memory - 跨线程协作内存使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1459224/

相关文章:

multithreading - 哪个Linux系统调用用于获取线程的ID?

c++ - 是否可以更改C/C++中自动变量的分配区域?

C++:动态内存分配和类构造函数

java - 峰值内存使用不超过限制

c++ - 如何确定 C++ 应用程序中的可用 RAM 量?

xcode - 获取当前执行的应用程序的PID

ios - -[UIApplication delegate] 只能从主线程调用

c++ - 防止客户端套接字程序崩溃cpp google protobuf

c - 在c中退出作用域时防止内存重用

android - 在另一个 Activity 启动后,如何在一个 Android Honeycomb Activity 中释放 Drawable 内存?