加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

内存 – Actors邮箱溢出.斯卡拉

发布时间:2020-12-16 10:01:25 所属栏目:安全 来源:网络整理
导读:我目前正与斯卡拉的两名演员合作.一个是生产者,它会生成一些数据并将其发送给一个游戏者.生产者通过消息发送HashMap [String,HashMap [Object,List [Int]]](以及标记发送者): parcer ! (this,data) 解析器一直在等待这样的消息: def act(){ loop{ react{ c
我目前正与斯卡拉的两名演员合作.一个是生产者,它会生成一些数据并将其发送给一个游戏者.生产者通过消息发送HashMap [String,HashMap [Object,List [Int]]](以及标记发送者):

parcer ! (this,data)

解析器一直在等待这样的消息:

def act(){
    loop{
      react{
        case (producer,data)=> parse(data);
      }
    }
}

该计划在正常的环境中运行良好.问题来自大量数据和许多消息发送(散列有大约10 ^ 4个元素,内部散列大约100个元素,列表长100),程序崩溃.它显示没有错误或异常.它只是停了下来.

问题似乎是我的生产者比解析器工作得快得多(目前我不想要多个解析器).

阅读scala mailbox size limit后,我想知道我的解析器的邮箱是否达到了它的极限.该帖子还提供了一些解决方案,但我首先需要确保这是问题所在.我该怎么测试呢?

有没有办法知道演员的记忆限制?如何读取邮箱中的已用/可用内存?

对于尚未在that link中发布的工作流程的任何建议也是受欢迎的.

谢谢,

解决方法

首先,您无需显式传递发件人,因为无论如何,Scala actors框架都会跟踪发件人.您始终可以使用方法发件人访问邮件的发件人.

从这里可以看出:scala.actors.MQueue,一个actor的邮箱被实现为链表,因此只受堆大小的限制.

尽管如此,如果您担心生产者非常快且消费者非常慢,我建议您探索一种限制机制.但我不建议从问题scala mailbox size limit的接受答案中采用这种方法.

通常,在系统受到严重压力时尝试发送过载消息似乎不是一个好主意.如果您的系统太忙而无法检查过载怎么办?如果过载消息的接收者太忙而无法对其进行操作怎么办?另外,删除消息对我来说听起来不是一个好主意.我认为您希望所有工作项目都可靠地处理.

另外,我不会依赖mailboxSize来确定负载.您无法区分不同的消息类型,您只能从消费者本身而不是生产者那里进行检查.

我建议使用消费者要求更多工作的方法,当他知道他可以处理它时.

下面是一个如何实现它的简单示例.

import scala.actors._
import Actor._

object ConsumerProducer {
  def main(args: Array[String]) {
    val producer = new Producer(Iterator.range(0,10000))
    val consumer = new Consumer(producer)
  }
}

case class Produce(count: Int)
case object Finished

class Producer[T](source: Iterator[T]) extends Actor {

  start

  def act() {
    loopWhile(source.hasNext) {
      react {
        case Produce(n: Int) => produce(n)
      } 
    }
  }

  def produce(n: Int) {
    println("producing " + n)
    var remaining = n
    source takeWhile(_ => remaining > 0) foreach { x => sender ! x; remaining -= 1 }
    if(!source.hasNext) sender ! Finished
  }
}

class Consumer(producer: Actor) extends Actor {

  start

  private var remaining = 0

  def act() {
    requestWork()
    consume()
  }

  def consume(): Nothing = react {
    case Finished => println("Finished")
    case n: Int => work(n); requestWork(); consume()
  }

  def requestWork() = if(remaining < 5) { remaining += 10; producer ! Produce(10) }

  def work(n: Int) = {
    println(n + ": " + (0 until 10000).foldLeft(0) { (acc,x) => acc + x * n })
    remaining -= 1
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读