【问题标题】:akka threads use 100% CPU while application is idle应用程序空闲时,akka 线程使用 100% CPU
【发布时间】:2014-05-05 14:16:15
【问题描述】:

我正在运行 AMD 四核处理器的 Ubuntu 12.04 系统上试验 akka / scala 2.10.3。

我编写了一个服务器,它在收到请求时应该执行一些计算。客户端将使用参与者消息发送一些数据(字符串列表)。当服务器上的 Actor 接收到列表时,它会将其拆分为四个列表,并让四个子 Actor 对列表进行排序。

到目前为止一切顺利:程序运行正常,我可以验证客户端是否收到了正确排序的列表。

但是,在服务器的行为中有两件事我不明白:

  1. 一旦我启动服务器,即使没有任何参与者在进行任何处理(他们都在等待消息),我的处理器的所有四个内核的使用率几乎都达到了 100%。这怎么可能?不应该只在安排某些参与者处理某些消息时才使用核心吗?
  2. 我曾预计,由四个参与者完成工作会自动暗示排序速度会提高四倍:每个参与者在单独的线程中运行,每个线程由不同的核心运行。然而,情况并非如此:没有观察到加速,甚至,基于actor的排序比普通的单线程排序慢得多。原因可能是我的调度程序配置,即默认配置不会自动利用多个核心吗?

编辑 按照 Dan Simon 的建议,我使用 visualvm 研究了问题 1。

visualvm 报告了几个大部分时间都在等待的调度程序线程(因此它们似乎没有使用太多的 CPU 时间)。 visualvm 还显示了其他几个一直在运行的线程,即使应用程序没有做任何事情;至少,我的代码都没有被执行。这些忙碌线程被命名为New I/O worker #1, #2, #4, #5New I/O boss #3New I/O server bossSignal DispatcherRMI TCP Connection(2)-127.0.0.1Attach ListenerRMI TCP Accept-0

我有一些编程 akka 的经验,但几乎没有配置它的经验,所以我无法理解上述信息。

【问题讨论】:

  • 默认调度程序使用 fork-join 调度程序,并且将有多个线程对应于物理内核的数量(我相信每个内核有 2 个),所以我怀疑还有另一个问题。我注意到 fork-join 有时会做很多忙等待,但不像你描述的那样。可以发一些代码吗?
  • @Dan Simon:感谢您的反馈。代码不够小,不能在这里发布,我可以将其上传到某个地方并在此处发布链接。或者您希望看到代码的哪些部分?
  • 不太确定,您的演员在构造时或在他们的preStart 方法中做任何事情吗?演员是否有任何类型的初始化消息或某种定期轮询工作?另外,您是否尝试过使用诸如 visualvm 之类的分析器来查看 CPU 的使用位置?
  • @Dan Simon:有些演员确实有一个preStart 方法,他们可以在其中创建子演员和/或发送一些消息。 Actors 也有一些初始化,但在那之后,它们会进入一个只等待传入消息的状态。据我所知,这不应该意味着轮询。我现在必须睡一会儿,但明天我会尝试使用分析器,看看是否能找到更多信息。感谢您的建议。

标签: multithreading scala akka


【解决方案1】:

“他们进入了只等待传入消息的状态”

当消息到达时通过回调方法通知参与者,还是参与者自己轮询某个队列以查看是否有新消息?

如果您正在轮询,发现没有工作,然后立即返回再次轮询(基本上忙于旋转),后者可能会导致 100% 的 cpu 使用率。修复方法是在再次轮询之前等待(Thread.yield()、LockSupport.parkNanos(1) 等)。

【讨论】:

  • 我们面临同样的问题。我们的利用率正在飙升至 800%,大多数 akka 演员都使用这个堆栈。 “default-akka.actor.default-dispatcher-10”:等待 [0x000000074e491db0] 上的通知。你能建议我们应该如何进行吗?
  • @prit kalra 尝试查找该线程是否像轮询一样忙于旋转,返回 false 因为没有被轮询,然后返回轮询。修复是在 poll() 返回 false 时采取等待策略。你可以试试 LockSupport.parkNanos(1)
  • Hastings 谢谢,找到了解决方案。实际上,默认调度程序和调度程序是在自定义调度程序之外创建的。默认调度程序可以创建不必要的线程,这些线程会导致线程饥饿并使用所有资源。
猜你喜欢
  • 2012-09-17
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2013-10-17
  • 2011-03-15
相关资源
最近更新 更多