Подтвердить что ты не робот

Java: массивы 1-d всегда смежны в памяти?

Многие книги/статьи, которые я прочитал по этой теме, а также небольшая программа, написанная с использованием "Небезопасная", показывают, что 1-мерные массивы в Java всегда смежны в памяти. Так это продиктовано JLS или это соглашение об осуществлении? Вопрос просят подтвердить это указание.

4b9b3361

Ответ 1

Нет, спецификация JVM не имеет таких гарантий: http://docs.oracle.com/javase/specs/jvms/se5.0/html/Concepts.doc.html#16446

На практике это, вероятно, так, но у вас также нет гарантии размера слова.

Unsafe не является стандартным Java-классом, поэтому, если ваша программа использует это, то он все равно не переносится...

Ответ 2

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

Обратите внимание, что использование Unsafe почти автоматически означает, что вы прогуливаетесь за пределы области спецификации.

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

Ответ 3

Я хочу обновить этот вопрос тем, что Спецификация языка Java, Java SE 8 Edition (JLS) и Об этом говорят спецификации виртуальной машины Java, Java SE 8 Edition (JVMS).

У нас есть выбор, чтобы ответить на этот вопрос:

  • Какие ограничения применяются для реализации JVM. Это самый надежный подход, поскольку реализация любой спецификации по сути предполагает принцип "Все, что не запрещено".
  • Что большинство реализаций JVM предлагают разумные

Я укажу на ограничения спецификации.

Если мы посмотрим на Глава 10. Массивы JLS (и любые другие главы JLS и JVMS связанные с массивами), мы не могли найти упоминания ограничений макета памяти, наложенных на массивы. Таким образом, это определенно означает, что массив может быть не непрерывным.

Кроме того, JLS говорит, что массивы - это объекты:

Глава 10. Массивы.

В языке программирования Java массивы объекты (§4.3.1), динамически создаются, а может быть присвоено переменные типа Object (§ 4.3.3). Все методы класса Object могут быть вызывается в массиве.
...

4.3.1. Объекты.

Объектом является экземпляр класса или массив. (и Array - Object)

И в то же время JVMS говорит, что объекты и массивы хранятся в куче:

2.5.3. Heap

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

Но JVMS не заставляет память кучи быть непрерывной:

2.5.3. Heap

... Память для кучи не обязательно должна быть непрерывной.

Поскольку все массивы хранятся в куче, а куча может быть не непрерывной, следует, что массивы также могут быть не непрерывными.

Ответ 4

Учитывая, что у многих JVM есть требование, чтобы куча была непрерывной в памяти, я думаю, что вряд ли они поместят 1d массив примитивов в разных местах памяти.

Объект, на который ссылается объект [], вряд ли будет непрерывным в памяти, и даже если он есть, можно переустановить без предупреждения.

Примечание. Используя Unsafe, вы можете читать ссылки в массиве как значения int, чтобы увидеть, что они есть до и после GC. Некоторые JVM используют 64-битные ссылки, требующие длинных, но наиболее часто используемых ссылок 32-bti (даже для 64-битных JVM).