java - Java/Scala 对垃圾回收做了哪些保证?

标签 java scala garbage-collection playframework-2.3

Play 框架有 play.api.libs.Files.TemporaryFile包含对 File 的引用,并在 TemporaryFile#finalize() 中将其删除。

case class TemporaryFile(file: File) {

  def clean(): Boolean = {
    file.delete()
  }

  def moveTo(to: File, replace: Boolean = false) {
    Files.moveFile(file, to, replace = replace)
  }

  override def finalize {
    clean()
  }

}

我知道这有一些问题,例如,您可以填满整个磁盘,而 JVM 并不觉得需要 GC。


但这里我问的是程序的“正确性”,即没有磁盘空间限制的程序。

def foo() {
    val tempFile = TemporaryFile(new File("/tmp/foo"))

    val inputStream = new FileInputStream(tempFile.file) // last use
    try {
        println(inputStream.read())
    } finally {
        inputStream.close()
    }
}

/foo/bar 可以在我从文件中读取之前删除吗? //last use 之后我没有使用 tempFile,所以它可以在那之后立即完成吗?

或者如果它作为参数传递给函数会怎么样?

def foo() {
  val tempFile = TemporaryFile(new File("/tmp/foo"))
  bar(tempFile)
}

def bar(tempFile: TemporaryFile) {
  val inputStream = new FileInputStream(tempFile.file) // last use
  try {
      println(inputStream.read())
  } finally {
      inputStream.close()
  }
}

如果在上面的示例中,tempFile 可能在我使用完它之前被删除,那么如何正确使用 TemporaryFile 才能避免这种情况发生?

最佳答案

一旦您不再拥有对该对象的强引用,Java 对象就有资格进行垃圾回收。这与您是否“使用”该对象无关。

在这个例子中,

def foo() {
    val tempFile = TemporaryFile(new File("/tmp/foo"))

    val inputStream = new FileInputStream(tempFile.file) // last use
    try {
        println(inputStream.read())
    } finally {
        inputStream.close()
    }
}

tempFile 不符合垃圾收集条件,因此最终确定,直到不再使用 foo()。使用 tempFile 中的成员的对象可能会使用它,并使其不符合条件的时间长于上次在 foo() 中使用的时间。

在这个例子中,

def foo() {
  val tempFile = TemporaryFile(new File("/tmp/foo"))
  bar(tempFile)
}

def bar(tempFile: TemporaryFile) {
  val inputStream = new FileInputStream(tempFile.file) // last use
  try {
      println(inputStream.read())
  } finally {
      inputStream.close()
  }
}

结果是一样的。

在一个小变体中(Java,我不太了解 Scala 语法),

class Foo {
    List<Object> objects = new List<Object>(); 
    void foo(Object o) { 
        objects.add(o); 
    }
}

// ...

Foo f = new Foo(); 
f.foo(new Object()); // The object we just created is not eligible for garbage 
                     // collection until the `Foo f` is not used, because
                     // it holds a strong reference to the object. 

关于java - Java/Scala 对垃圾回收做了哪些保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25715018/

相关文章:

java - 不使用RequestDispatcher forward和Servlet Annotation

Java:使用正则表达式 .*-\\d+{.*}\\d+-.* 引发 PatternSyntaxException

c++ - 嵌入式 Ruby GC 和包装结构

java - 当我从map和hashmap创建对象时有什么区别

java - JUnit 和 Mockito 的分支覆盖率

尝试加载 opencv 时出现 java.lang.UnsatisfiedLinkError

scala - Future Recursion Patterns/Future Chaining 任意长度

斯卡拉 : Nested getOrElse

java - Java 中不分配返回值的非 void 方法调用

java - 垃圾收集斯坦福 Maxent POS 标记器