【问题标题】:Scala StackOverflowError when getting value from Map从 Map 获取值时出现 Scala StackOverflowError
【发布时间】:2017-05-07 00:32:07
【问题描述】:

经过一些重构后,我们突然发现在运行时发生了这种情况:

java.lang.StackOverflowError: null
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)

我们发现了类似的问题,但没有一个完全有这样的痕迹:

【问题讨论】:

    标签: scala stack-overflow scala-collections


    【解决方案1】:

    上述问题指向MapLike.mapValues的懒惰,经过进一步研究我们找到了原因。

    我们有一些定期调用的清理代码并执行以下操作:

      case class EvictableValue(value: String, evictionTime: Instant)
    
      val startData = Map(
        "node1" -> Map(
          "test" -> EvictableValue("bar",  Instant.now().plusSeconds(1000))
        )
      )
    
      // every n seconds we do the below code
      // here simulated by the fold
      val newData = (1 to 20000).foldLeft(startData){(data, _) =>
        data.mapValues { value =>
          value.filter(_._2.evictionTime.isBefore(Instant.now()))
        }
      }
    
      // this stack overflows
      val result = newData.get("test")
    

    解决方案是切换到Map.transform

    data.transform { (_, value) =>
        value.filter(_._2.evictionTime.isBefore(Instant.now()))
    } 
    

    或者按照here的解释强制查看

    data.mapValues{ value =>
        value.filter(_._2.evictionTime.isBefore(Instant.now()))
    }.view.force
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-15
      • 2011-04-19
      • 2017-09-08
      • 1970-01-01
      • 2019-06-01
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多