Может ли массив JVM быть realloc () 'd? - PullRequest
0 голосов
/ 25 мая 2019

Таким образом, язык C имеет realloc() процедуру, которую можно использовать для увеличения выделенной памяти [править] память на месте.

Существует ли эквивалентная концепция для JVM / Java? Или за Array с или nio.Buffer с? Я не против, является ли это частью JDK или как внешней библиотекой, например. sun.unsafe.

1 Ответ

2 голосов
/ 29 мая 2019

Прежде всего, функция C realloc - это не инструмент, который может увеличивать массивы , а память, ранее выделенная с помощью malloc, calloc или realloc . Напротив, массивы C могут находиться в стеке или статической области памяти и даже могут быть встроены в более крупную структуру.

Затем функция имеет семантику аннулирования исходного указателя, как это делает free, и возврата нового указателя. Поэтому, если у вас есть копии указателя, вы обязаны заменить все вхождения новым указателем.

Конечно, Java не поддерживает недействительные ссылки. Гарантия достоверности каждой не null ссылки на объект является фундаментальным свойством управления памятью Java.

Так что, если вы хотите получить эквивалент C realloc, вам придется использовать указатели, а не массивы. Тогда sun.misc.Unsafe имеет все связанные операции

  • public long allocateMemory(long bytes)
  • public long reallocateMemory(long address, long bytes)
  • public void freeMemory(long address)
  • public float getXyz(long address) ¹
  • public void putXyz(long address, xyz x) ¹

¹ где «xyz» обозначает примитивный тип

Если вы хотите изменить размер массива, используйте

array = Arrays.copyOf(array, newSize);

это не сделает недействительными старые ссылки, поэтому, если вам не удастся заменить все ссылки на старый массив, код, использующий эти старые ссылки, получит доступ к старому массиву.

Но если array является единственной ссылкой на конкретный массив или ваш код явно заменяет все существующие ссылки, JVM теоретически может включить операцию изменения размера на месте вместо копирования содержимого, см. также Работает ли Java JIT при запуске кода JDK?

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

Для JVM, имеющей такую ​​оптимизацию, вы можете получить преимущество автоматически при многократном добавлении к

ArrayList, поскольку этот класс гарантирует, что он является единственным держателем ссылки на свой внутренний массив и он использует Arrays.copyOf для изменения размеров.

...