scala - 构造函数参数是否得到GC校验?

标签 scala constructor garbage-collection

我正在使用一个系统,该系统需要使用事务初始化许多对象,并且出于超出此问题范围的原因,这些事务必须传递到构造函数中。像这样:

trait Mutable

class Txn(i: Int) {
  def newID(implicit m: Mutable): Int = i
  override def finalize(): Unit = println("Finalised " + i)
}

class User(t0: Txn) extends Mutable {
  val id = t0.newID(this)
}

现在,我担心垃圾收集事务存在问题:
val u = new User(new Txn(1234))
System.gc()  // hmmm, nothing seems to happen?

所以我的问题是:t0构造函数参数是否曾经被垃圾收集过,还是在这里创建了内存泄漏?在一个等效的Java代码中,我想我会有这样的东西:
public class User implements Mutable {
    final int id;
    public User(Txn t0) {
        id = t0.newID(this);
    }
}

并且我确定t0已收集。但这在Scala案中是真的吗?

如果没有,如何确保t0被垃圾回收?请记住,我必须将事务作为构造函数参数传递,因为User类实现了必须传递到Txn的方法中的某些特征,因此在构造newID之前不能调用这些方法(例如User)。

之前,我尝试过使用大量的lazy相互依赖的val来构造使用用户对象之外的事务的所有东西,但这确实很麻烦。例如,这已经是一半不可读了,它会产生堆栈溢出:
trait User extends Mutable { def id: Int }

def newUser(implicit tx: Txn): User = {
  lazy val _id: Int = tx.newID(u)
  lazy val u  = new User { val id: Int = _id } // oops, should be lazy val id!
  u
}

val u = newUser(new Txn(1234))

您可以想象,确实很烂,编译器在这里找不到丢失的惰性val的问题,因此我绝对希望使用构造函数arg变体。

最佳答案

如果绝对必要,建议您使用javap来查看该类已编译到的内容。避免将构造函数参数转换为类参数的一些规则:

  • 不要在deflazy val上使用它。
  • 不要在进行模式匹配的分配中使用它(例如val (a, b) = f(x))。
  • 当然,不要将其声明为valvar
  • 关于scala - 构造函数参数是否得到GC校验?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8643219/

    相关文章:

    scala - 为什么 scalac 需要在期望 `Int` 的方法中装箱 `Any`

    c++ - 返回值优化的魔力是什么?

    Python - 打印出对特定实例的所有引用

    java - java中集合的弱引用

    unit-testing - 在 play 2.0 scala 中在同一个 FakeApplication() 中运行多个测试

    scala - 函数式编程 : is foldLeft is the parent method of all functional methods such as foldRight, 映射、过滤器

    arrays - ArrayBuffer 和 Array 有什么区别

    c++ - 如何将 my_alloc 用于 C++ 中的_all_ 新调用?

    C#自定义数据类型!

    object - 为什么 JVM GC 喜欢不可变对象(immutable对象)?