Многие книги/статьи, которые я прочитал по этой теме, а также небольшая программа, написанная с использованием "Небезопасная", показывают, что 1-мерные массивы в Java всегда смежны в памяти. Так это продиктовано JLS или это соглашение об осуществлении? Вопрос просят подтвердить это указание.
Java: массивы 1-d всегда смежны в памяти?
Ответ 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).