Размер кучи Java/Kotlin

Я пытаюсь понять, какие космические объекты занимают память в куче при инициализации, но я не могу найти точную информацию по этому поводу, поэтому на мой вопрос даются эти 2 примера, по 3 класса в каждом, каков будет порядок размер, занимаемый каждым экземпляром? Я знаю, что каждый int занимает пространство в 4 байта, но разве объявление его как val или var не меняет это, как в классе C? Изменяет ли наличие метода получения его, как в классе 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, где есть как параметры, так и геттеры, а также функция внутри класса со своими параметрами и переменными?

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
    }
  }
}

Вы спрашиваете о размере класса или экземпляров?

aled 01.07.2024 20:00

Вопрос о размере экземпляров в куче.

nuno 01.07.2024 20:08
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это сложный вопрос, требующий рассмотрения многих переменных, поэтому я сделаю некоторые предположения.

Для стандартной JVM Hotspot (версии <= 22, это будет применяться и к будущим версиям, но не навсегда. Никакой лилипутии)

32-битные системы

  • Заголовок объекта занимает 8 байт.
  • Примитивные поля принимают стандартные размеры.
    • байт = 1
    • короткий = 2
    • символ = 2
    • интервал = 4
    • длинный = 8
    • число с плавающей запятой = 4
    • двойной = 8
  • Поля ссылок (объектов) занимают 4 байта.
  • Размер объекта дополняется (округляется вверх) до ближайших 4 байтов.

64-битные системы

  • Заголовок объекта занимает 12 байт.
  • Примитивные поля принимают стандартные размеры.
    • Смотреть выше
  • Поля ссылок (объектов) занимают 8 байтов (или 4 байта при использовании сжатых ООП, что вероятно для приложений с размером кучи менее 32 ГБ).
  • Размер класса дополняется (округляется вверх) до ближайших 4 байтов.

Итак, для следующего класса Java в 64-битной системе со сжатыми указателями

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 байта

Примеры Котлина

Первый блок кода

Класс А

В классе A свойства x и z поддерживаются полями, каждое из которых занимает 4 байта. Свойство y не поддерживается полем, поскольку к нему прикреплен метод получения и не занимает места в экземплярах объектов.

Общий размер составит (12 + 4 + 0 + 4) ceil 8 = 24

Класс Б

В классе B все свойства поддерживаются полями и каждое занимает 4 байта.

Общий размер составит (12 + 4 + 4 + 4) ceil 8 = 24

Класс С

В классе C, потому что val или var не привязаны к параметрам конструктора, то есть все, что они собой представляют, параметры конструктора. Параметр метода или конструктора не сохраняется и не может занимать место в куче.

Общий размер составит (12 + 0 + 0 + 0) ceil 8 = 16

Второй блок кода

Методы в Java и Kotlin не занимают дополнительного места при выделении кучи объекта для каждого экземпляра.

Класс А

Класс A не имеет свойств, поддерживаемых полями (поскольку у них есть геттеры), и ему потребуется только 16 байтов на экземпляр.

Класс Б

Класс B имеет два свойства, поддерживаемых полем int, и ему потребуется 24 байта на каждый экземпляр.

Класс С

Класс C имеет одно свойство, поддерживаемое полем int, и ему потребуется 16 байтов на экземпляр.

Ваше здоровье! И последний вопрос: в классе C из второго примера свойство функции, вложенной в класс, и две объявленные переменные внутри не являются свойствами, поддерживаемыми полем?

nuno 01.07.2024 20:31

Нет, это не так. Ничто, определенное в функции, не занимает память в экземпляре класса C, а nr поддерживается геттером, а не полем.

Louis Wasserman 01.07.2024 20:35

понятно! Спасибо!

nuno 01.07.2024 20:38

Другие вопросы по теме