Spark:在 Scala 中将 cogroup 与 ListBuffer 一起使用时出现内存问题(超出 GC 开销限制)
Spark: memory issues (GC overhead limit exceeded) when using cogroup with ListBuffer in Scala
我有以下代码:
fTuple2.cogroup(gTuple2).flatMap { t =>
val fList: ListBuffer[classF] = ListBuffer()
val gList: ListBuffer[classG] = ListBuffer()
while (t._2._2.iterator.hasNext) {
gList.add(t._2._2.iterator.next)
}
val fIter = t._2._1.iterator
while (fIter.hasNext) {
val f = fIter.next
val hn = f.getNum()
//-----------------
try {
val gValue = FindGUtiltity.findBestG(hn, gList)
f.setG(gValue)
} catch {
case e: Exception => println("exception caught: " + e);
}
fList.add(f)
}
fList
}
并在行:
gList.add(t._2._2.iterator.next)
我收到以下错误:
java.lang.OutOfMemoryError: GC overhead limit exceeded
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:176)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:45)
at scala.collection.mutable.BufferLike$class.appendAll(BufferLike.scala:147)
at scala.collection.mutable.AbstractBuffer.appendAll(Buffer.scala:48)
at scala.collection.mutable.BufferLike$class.append(BufferLike.scala:142)
at scala.collection.mutable.AbstractBuffer.append(Buffer.scala:48)
at scala.collection.convert.Wrappers$MutableBufferWrapper.add(Wrappers.scala:80)
当 gList 大小为 1 时,它工作正常。但如果平均 gList 大小约为 5,则会出现内存问题。 classG 的实例总数并不太大,因此总的 gList 不应该太大。 gList 实际上是在 Scala 中自我复制吗?有没有更好的方法在 Scala 中创建列表?还是我应该在这里使用一些 Java 列表?
谢谢!
只要至少有一个元素要迭代,你的 while 循环就永远不会结束,因为你在每个循环中请求一个新的迭代器,并且每次都获取第一个元素,将它添加到一个列表中,这会破坏内存.
这就是为什么(根据您的评论)仅获取一次迭代器并将其分配给 val 即可解决问题的原因。
我有以下代码:
fTuple2.cogroup(gTuple2).flatMap { t =>
val fList: ListBuffer[classF] = ListBuffer()
val gList: ListBuffer[classG] = ListBuffer()
while (t._2._2.iterator.hasNext) {
gList.add(t._2._2.iterator.next)
}
val fIter = t._2._1.iterator
while (fIter.hasNext) {
val f = fIter.next
val hn = f.getNum()
//-----------------
try {
val gValue = FindGUtiltity.findBestG(hn, gList)
f.setG(gValue)
} catch {
case e: Exception => println("exception caught: " + e);
}
fList.add(f)
}
fList
}
并在行:
gList.add(t._2._2.iterator.next)
我收到以下错误:
java.lang.OutOfMemoryError: GC overhead limit exceeded
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:176)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:45)
at scala.collection.mutable.BufferLike$class.appendAll(BufferLike.scala:147)
at scala.collection.mutable.AbstractBuffer.appendAll(Buffer.scala:48)
at scala.collection.mutable.BufferLike$class.append(BufferLike.scala:142)
at scala.collection.mutable.AbstractBuffer.append(Buffer.scala:48)
at scala.collection.convert.Wrappers$MutableBufferWrapper.add(Wrappers.scala:80)
当 gList 大小为 1 时,它工作正常。但如果平均 gList 大小约为 5,则会出现内存问题。 classG 的实例总数并不太大,因此总的 gList 不应该太大。 gList 实际上是在 Scala 中自我复制吗?有没有更好的方法在 Scala 中创建列表?还是我应该在这里使用一些 Java 列表?
谢谢!
只要至少有一个元素要迭代,你的 while 循环就永远不会结束,因为你在每个循环中请求一个新的迭代器,并且每次都获取第一个元素,将它添加到一个列表中,这会破坏内存.
这就是为什么(根据您的评论)仅获取一次迭代器并将其分配给 val 即可解决问题的原因。