Memory 跨线程协作内存使用?

Memory 跨线程协作内存使用?,memory,multithreading,memory-management,Memory,Multithreading,Memory Management,我有一个应用程序,它有多个线程处理todo队列中的工作。我对进入队列的内容和顺序没有任何影响(由用户从外部输入)。队列中的单个工作项可能需要几秒钟到几个小时的运行时间,在处理过程中不应中断。此外,单个工作项可能会消耗几兆字节到大约2GB的内存。内存消耗是我的问题。我在一台8GB机器上以64位进程的形式运行,该机器有8个并行线程。如果它们中的每一个同时命中一个最坏情况的工作项,我的内存就会耗尽。我想知道解决这个问题的最佳方法 保守地计划,只运行4个线程。最坏的情况应该不再是问题了,但是我们浪费了很

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

  • 保守地计划,只运行4个线程。最坏的情况应该不再是问题了,但是我们浪费了很多并行性,使得平均情况慢了很多
  • 在开始一个新项目之前,让每个线程检查可用内存(或者所有线程分配的总内存)。仅在剩余内存超过2GB时启动。定期重新检查,希望其他线程完成它们的内存占用,我们最终可以开始
  • 尝试预测队列中的项目需要多少内存(硬),并相应地计划。我们可以重新排序队列(覆盖用户选择),或者简单地调整正在运行的工作线程的数量
  • 更多的想法 我现在倾向于第二个,因为它似乎很容易实现和解决大多数情况。然而,我仍然想知道,有什么标准的方法来处理这种情况?毕竟,操作系统必须在进程级别执行非常类似的操作

    问候,

    Sören
    

    在不知道自己在做什么的情况下很难提出解决方案,但是考虑一下:

  • 查看您的处理算法是否可以在不将整个工作项加载到内存的情况下访问较小部分的数据
  • 考虑开发一个基于服务的解决方案,以便工作由另一个进程(可能是web服务)执行。通过这种方式,您可以扩展解决方案以在多台服务器上运行,也许可以使用负载平衡器来分发工作
  • 在处理传入的工作项之前,是否将其持久化到磁盘?如果不是,它们可能无论如何都应该是,特别是在处理器到达它们之前的一段时间
  • 内存使用量是否与传入工作项的大小成比例,或者是否易于计算?了解这一点将有助于决定如何安排处理

  • 希望有帮助

    因此,当前最坏情况下的内存使用率是16GB。由于只有8GB的RAM,在操作系统和系统进程共享内存后,您将幸运地剩下6或7GB。因此,平均而言,在一个中等负载的系统上,您已经在消耗内存了。这台机器有多少芯?您是否有8个工作线程,因为它是8核机器

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

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

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

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


    然后是“增加可用内存”。在价格/性能方面,你应该认真考虑简单地购买更多的RAM。有时,为了达到相同的最终结果,投资更多的硬件比开发时间要便宜。例如,您可以花几百美元投入32GB的RAM,这将立即提高性能,而不会增加解决方案的复杂性。在性能压力消失的情况下,您可以对应用程序进行分析,以了解如何提高软件的效率。

    我在Herb Sutter的博客上继续了讨论,并提供了一些非常有用的读者评论。如果你感兴趣的话,请前往

    谢谢你到目前为止提出的所有建议

    Sören
    

    我完全同意“减少消耗”这一点——我们在这方面非常努力,并且已经在计算单个字节了。顺序/延迟加载是我们想要做的事情,但由于随机访问模式,这非常困难。它正在酝酿中,但目前还很遥远。。。是的,这是一台8芯的机器。我会询问购买更多内存的问题,但这不仅仅是一台机器,而是很多机器——我们也会在不同的机器之间进行比较。如果您描述了处理算法的性质,那么提供更多相关建议就更容易了。我想到的一件事是,您可能能够对数据进行初始传递以构建索引,然后在处理过程中使用此信息优化数据加载和访问策略。数据由成对的二进制文件组成,即调用图和流程图。我们正在进行结构上的比较来衡量相似性。