Java/Kotlin 堆大小

问题描述 投票:0回答:1

我试图了解初始化时堆中内存中占用的空间对象,但我找不到这方面的明确信息,所以我的问题是给出这 2 个示例,每个示例有 3 个类,顺序是什么每个实例占用的大小? 我知道每个 int 占用 4 个字节的空间,但是将其声明为 val 或 var 不会像 C 类中那样改变它吗?拥有 getter 方法是否也会像 A 类中那样改变它?

class A (
    val x: Int = 999,
    val y: Int get() = 999,
    var z: Int = -1
)

class B (
    val x: Int = 0,
    val y: Int = 999,
    val z: Int = -1
)

class C (
    x: Int = 999,
    y: Int = 999,
    z: Int = 999
)

在第二个示例中,像 A 中那样声明函数是否会影响大小?那么在 B 中,只有类参数被调用呢? C 语言怎么样,它既有参数又有 getter,而且类中还有一个函数,有自己的参数和变量?

class A {
  fun foo() = 123456
  val nr: Int get() = 7658894
  val foo: Int get() = nr

  class B(val bar: Int, val foo: Int)

  class C(val bar: Int) {
    val nr: Int get() = bar
    fun foo() = nr
    fun oper(num: Int): Int {
      val x = num + 1
      val y = num - 1
      return x * y
    }
  }
}
java kotlin runtime heap
1个回答
0
投票

这是一个复杂的问题,需要考虑很多变量,所以我会做出一些假设

对于标准 Hotspot JVM(版本 <= 22, this will apply to future versions too, but not forever. No Lilliput)

32 位系统

  • 对象的头部占用8个字节
  • 原始字段采用标准大小
    • 字节 = 1
    • 短 = 2
    • 字符 = 2
    • int = 4
    • 长 = 8
    • 浮动= 4
    • 双 = 8
  • 引用(对象)字段占用 4 个字节
  • 对象大小被填充(向上舍入)到最接近的 4 个字节

64 位系统

  • 对象的头部占用12个字节
  • 原始字段采用标准大小
    • 看上面
  • 引用(对象)字段占用 8 个字节或(使用 4 个字节压缩 OOP,这可能适用于堆小于 32GB 的应用程序)
  • 类大小被填充(向上舍入)到最接近的 4 个字节

因此对于 64 位系统中具有压缩指针的以下 Java 类

class Hello {
    public byte a;
    public String b;
    public int c;
}

对象大小将为

12 + 1 + 4 + 4 = 21 (24 when rounded up to the nearest 8)
24 字节

Kotlin 示例

第一个代码块

A级

在 A 类中,属性 x 和 z 由字段支持,每个属性占用 4 个字节。属性 y 不受字段支持,因为它附加了一个 getter 并且在对象实例中不占用空间

总尺寸为

(12 + 4 + 0 + 4) ceil 8 = 24

B级

在 B 类中,所有属性都由字段支持,每个属性占用 4 个字节。

总尺寸为

(12 + 4 + 4 + 4) ceil 8 = 24

C级

在C类中,因为

val
var
没有附加到构造函数参数上,所以它们只是构造函数参数。方法或构造函数的参数不会持久化,也不会占用堆中的空间。

总尺寸为

(12 + 0 + 0 + 0) ceil 8 = 16

第二个代码块

© www.soinside.com 2019 - 2024. All rights reserved.