gpt4 book ai didi

scala - 最终 val 会增加对象大小吗?

转载 作者:行者123 更新时间:2023-12-04 11:54:11 30 4
gpt4 key购买 nike

class Foo {
final val pi = 3
}

是否每 Foo对象有一个 pi成员?因此我应该把 pi在伴生对象中?

最佳答案

如果您担心内存占用,您可以考虑将此字段移动到伴随对象中。

是的,类的每个实例 Foo将有 pi value -- Scala 编译器不会消除这个声明。 JVM 反射允许您删除类成员上的 final 修饰符,以及 Unsafe object 甚至允许修改这些。所以——Scala 编译器可以通过删除这个字段来生成具有惊人结果的代码,所以这个优化没有被应用。

...
minor version: 0
major version: 50
flags: ACC_PUBLIC, ACC_SUPER
...
{
private final int pi;
flags: ACC_PRIVATE, ACC_FINAL


public final int pi();
flags: ACC_PUBLIC, ACC_FINAL
LineNumberTable:
line 243: 0
LocalVariableTable:
Start Length Slot Name Signature
...

事实上,一些编译器转换(例如特化)甚至可能会删除底层成员的 final 修饰符,所以感觉 final在 Scala 代码中可能不是 final在字节码级别。

这个:
class Foo[@specialized T] {
final val pi: T = null.asInstanceOf[T]
}

变成:
  ...
public final T pi;
flags: ACC_PUBLIC, ACC_FINAL
Signature: #9 // TT;


public T pi();
flags: ACC_PUBLIC
LineNumberTable:
line 243: 0
...

以上, pi访问器方法(即它的 getter)不再是最终的。

Oracle JVM 中的 JIT 也不会在运行时从内存中的对象表示中删除该成员 - Foo 的运行时大小。 32 位 JVM 上的对象将是 16 字节(8 字节对象 header + 4 字节用于整数字段,四舍五入到 8 字节边界)。然而,JIT 可能会决定将来自最终字段的常量值内联到代码的部分中,以便消除一些字段写入。

关于scala - 最终 val 会增加对象大小吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17615896/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com