Akka线程在应用程序空闲时使用100%的CPU

5
我正在一台装有 AMD 四核处理器的 Ubuntu 12.04 系统上实验使用 akka/scala2.10.3。我编写了一个服务器,它在接收到请求时应该执行一些计算。客户端将使用一个 actor 消息发送一些数据 (字符串列表)。当服务器上的 actor 接收到列表时,它会将它分成四个列表,并让四个子 actor 对列表进行排序。
到目前为止还不错,该程序可以工作并且我可以验证客户端接收到正确排序的列表作为结果。
然而,有两件事情我不明白服务器行为中存在:
1. 只要我启动服务器,即使没有 actor 进行任何处理 (它们都在等待消息),我的处理器的所有四个内核使用率就会升至近乎 100%。这是怎么可能的?内核不应该只在安排处理某些消息时才被使用吗?
2. 我原本期望由四个 actor 完成的工作会自动意味着排序速度会提高四倍:每个 actor 都在单独的线程中运行,每个线程都由不同的内核运行。然而,情况并非如此: 没有观察到加速或者甚至,基于 actor 的排序比纯单线程排序要慢得多。原因可能是调度程序配置,即默认配置未能自动利用多个内核吗?

默认的调度程序使用fork-join调度器,将拥有与物理核心数量相对应的多个线程(我相信每个核心有2个线程),因此我怀疑还有其他问题。我注意到fork-join有时会做很多忙等待,但不像您描述的那样。您能发布一些代码吗? - Dan Simon
@Dan Simon:感谢您的反馈。代码不够小,无法在此处发布,我可以将其上传到其他地方并在此处发布链接。或者您想看到代码的哪些部分? - Giorgio
不太确定,你的演员在构造或者preStart方法中做了什么?演员是否有任何初始化消息或者定期轮询工作的方式?另外,你是否尝试过使用类似visualvm这样的分析工具来查看CPU的使用情况? - Dan Simon
@Dan Simon:有些演员确实有一个preStart方法,在其中创建子演员和/或发送一些消息。演员还有一些初始化,但之后,它们就进入了一个状态,只等待传入的消息。据我所知,这不应意味着轮询。我现在得休息一下,但明天我会尝试使用分析器,看看能否找到更多信息。感谢您的建议。 - Giorgio
1个回答

0

它们进入一种状态,只等待传入的消息。

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

如果您正在轮询并发现没有工作,然后立即返回进行轮询(实质上是忙碌自旋),后者可能会导致100%的CPU使用率。解决方法是在再次轮询之前等待一段时间(Thread.yield(),LockSupport.parkNanos(1)等)。


我们正在面临相同的问题。我们的利用率飙升到800%,大部分akka actors都有这个堆栈跟踪。 "default-akka.actor.default-dispatcher-10":正在等待[0x000000074e491db0]的通知。您能建议我们如何继续吗? - prit kalra
@prit kalra 尝试查找该线程是否正在忙碌自旋(轮询),如果返回false,表示没有进行轮询,然后立即回到轮询状态。修复方法是如果poll()返回false,则加入等待策略。您可以尝试使用LockSupport.parkNanos(1)等待一段时间。 - CaptainHastings
谢谢,找到了解决方案。实际上,默认的调度程序和调度器是与自定义调度程序分开创建的。默认的调度程序可能会创建不必要的线程,这些线程会导致线程饥饿并使用所有资源。 - prit kalra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接