这种奇怪的Scala内存泄漏的原因是什么? [英] What is the cause of this strange Scala memory leak?

查看:267
本文介绍了这种奇怪的Scala内存泄漏的原因是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使有7G的堆空间,这也将耗尽内存.

import scala.collection.mutable.Set

class Foo() {
  val anEmptySet: Set[Int] = Set()
  def bar(ints: Traversable[Int]): Unit = {}
  override def finalize() {
    bar(anEmptySet)
    super.finalize()
  }

}

object FooTest {
  def main(args: Array[String]): Unit = {
    for (i <- 0 to 100000000) {
      val f = new Foo()
    }
  }
}

是什么原因导致该问题,如何避免该问题?问题似乎是在finalize方法中对bar的调用,但是我不明白为什么它会泄漏内存.我知道典型的类不需要重写finalize,但是在此代码的实际版本中这是必需的.

解决方案

正如我在评论中所说,这根本不是Scala特有的问题. finalize直接来自java.lang.Object. 此答案对问题的描述非常好,尽管我会毫不犹豫地说这个问题是重复的. >

要点是finalize需要被某些东西调用.但是,当您快速连续创建1000亿个对象时,它们的创建速度比最终确定的速度快得多.该线程需要可以调用finalize,但这不是因为它忙于创建更多对象.

如何解决?您可以先不快速创建同一对象的1000亿个实例开始.我知道这只是一个玩具示例,但是在现实世界中,您将不得不避免同时分配过多的这些示例.鉴于这不是实际的问题代码,因此很难提供更好的建议.

Even with 7G of heap space, this will run out of memory.

import scala.collection.mutable.Set

class Foo() {
  val anEmptySet: Set[Int] = Set()
  def bar(ints: Traversable[Int]): Unit = {}
  override def finalize() {
    bar(anEmptySet)
    super.finalize()
  }

}

object FooTest {
  def main(args: Array[String]): Unit = {
    for (i <- 0 to 100000000) {
      val f = new Foo()
    }
  }
}

What is causing the problem, and how can it be avoided? The problem seems to be the call to bar in the finalize method, but I don't understand why it would leak memory. I know that typical classes don't need to override finalize, but it is necessary in the real version of this code.

解决方案

As I said in the comments, this is not at all a Scala-specific problem. finalize comes straight from java.lang.Object. The problem is described very well by this answer, though I would hesitate to say that this question is an exact duplicate.

The gist of it is that finalize needs to be called by something. But when you're creating 100 billion objects in rapid succession, they are getting created much faster than they can be finalized. The thread needs to be available to call finalize, but it isn't because it's too busy creating more objects.

How can you fix it? You could start by not creating 100 billion instances of the same object in rapid succession. I know this is just a toy example, but in the real world you'll have to try to avoid allocating too many of these at the same time. And given this is not the actual code in question, it's harder to give better advice.

这篇关于这种奇怪的Scala内存泄漏的原因是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆