Рубрики
Без рубрики

Проект Java Valhalla

Узнайте о проекте Valhalla – о текущем состоянии разработки и о том, что он предлагает для повседневного разработчика Java, как только он будет выпущен.

Автор оригинала: Kevin Wittek.

1. Обзор

В этой статье мы рассмотрим Project Valhalla – исторические причины этого, текущее состояние разработки и то, что она представляет для повседневного разработчика Java после ее выпуска.

2. Мотивация и причины проекта “Валгалла”

В одном из своих выступлений Брайан Гетц , архитектор языка Java в Oracle, сказал, что одной из главных мотиваций проекта Valhalla является желание адаптировать язык Java и среду выполнения к современному оборудованию . Когда был задуман язык Java (примерно 25 лет назад на момент написания статьи), стоимость извлечения памяти и арифметической операции была примерно одинаковой.

В настоящее время ситуация изменилась, и операции извлечения памяти стали в 200-1000 раз дороже арифметических операций. С точки зрения языкового дизайна это означает, что в направлениях, ведущих к извлечению указателей, это отрицательно влияет на общую производительность.

Поскольку большинство структур данных Java в приложении являются объектами, мы можем считать Java языком с большим количеством указателей (хотя обычно мы не видим их и не манипулируем ими напрямую). Эта реализация объектов на основе указателей используется для обеспечения идентификации объектов, которая сама по себе используется для таких языковых функций, как полиморфизм, изменчивость и блокировка. Эти функции доступны по умолчанию для каждого объекта, независимо от того, действительно ли они нужны или нет.

Следуя цепочке идентификаций, ведущей к указателям, и указателям, ведущим к косвенным ссылкам, с косвенными ссылками, имеющими недостатки в производительности, логическим выводом является удаление тех из структур данных, которые в них не нуждаются. Именно здесь в игру вступают типы значений.

3. Типы значений

Идея типов значений состоит в том, чтобы представлять чистые агрегаты данных . Это связано с удалением функций обычных объектов. Итак, у нас есть чистые данные, без идентификации. Это, конечно, означает, что мы также теряем функции, которые могли бы реализовать с помощью идентификации объекта. Следовательно, сравнение равенства может происходить только на основе состояния. Таким образом, мы не можем использовать репрезентативный полиморфизм, и мы не можем использовать неизменяемые или ненулевые объекты.

Поскольку у нас больше нет идентификатора объекта, мы можем отказаться от указателей и изменить общую компоновку памяти типов значений по сравнению с объектом. Давайте рассмотрим сравнение расположения памяти между классом Point и соответствующим типом значения Point.

Код и соответствующая компоновка памяти обычного точечного класса будут:

final class Point {
  final int x;
  final int y;
}

С другой стороны, код и соответствующая компоновка памяти типа значения Точка будут:

value class Point {
  int x;
  int y
}

Это позволяет JVM сглаживать типы значений в массивы и объекты, а также в другие типы значений. На следующей диаграмме мы представляем отрицательный эффект косвенных ссылок при использовании класса Point в массиве:

С другой стороны, здесь мы видим соответствующую структуру памяти типа значения Point[] :

Это также позволяет JVM передавать типы значений в стек вместо того, чтобы распределять их в куче. В конце концов, это означает, что мы получаем агрегаты данных, поведение которых во время выполнения похоже на примитивы Java, такие как int или float .

Но в отличие от примитивов, типы значений могут иметь методы и поля. Мы также можем реализовать интерфейсы и использовать их в качестве универсальных типов. Таким образом, мы можем взглянуть на типы значений с двух разных точек зрения:

  • Более быстрые объекты
  • Определяемые пользователем примитивы

В качестве дополнительной глазури на торте мы можем использовать типы значений в качестве универсальных типов без упаковки. Это напрямую приводит нас к другой важной функции проекта Valhalla: специализированные дженерики.

4. Специализированные Дженерики

Когда мы хотим обобщить примитивы языка, в настоящее время мы используем коробочные типы, такие как Integer для int или Float для float . Этот бокс создает дополнительный уровень косвенности, тем самым сводя на нет цель использования примитивов для повышения производительности в первую очередь.

Поэтому мы видим множество специальных специализаций для примитивных типов в существующих фреймворках и библиотеках, таких как IntStream или ToIntFunction . Это делается для повышения производительности при использовании примитивов.

Таким образом, специализированные дженерики-это попытка устранить потребности в этих “взломах”. Вместо этого язык Java стремится включить универсальные типы практически для всего: ссылок на объекты, примитивов, типов значений и, возможно, даже void .

5. Заключение

Мы взглянули на изменения, которые проект Valhalla внесет в язык Java. Две из основных целей-повышение производительности и уменьшение утечек абстракций.

Повышение производительности достигается за счет выравнивания графиков объектов и удаления косвенных ссылок. Это приводит к более эффективному размещению памяти и меньшему количеству выделений и сборок мусора.

Лучшая абстракция достигается за счет примитивов и объектов, имеющих более схожее поведение при использовании в качестве универсальных типов.

Ранний прототип проекта Valhalla, вводящий типы значений в существующую систему типов, имеет кодовое имя LW1 .

Мы можем найти более подробную информацию о проекте Valhalla на соответствующей странице проекта и джипах: