Pull to refresh

Comments 20

UFO landed and left these words here

Описание массивов в статье на 95% касается Kotlin. Про Си лишь упоминания в качестве контраста реализаций. Детально о массивах в Си можно прочитать в других статьях :D

За замечание о доступе к элементам — спасибо!

UFO landed and left these words here

Kotlin все равно реализован на сях (ИМХО)

Эээ, нет

UFO landed and left these words here

На Java и Kotlin. В частности, ArrayList для JVM BE просто алиасится в java.util.ArrayList, написанный на Java

UFO landed and left these words here

Компилятор Java написан, не поверите, на Java. JVM написана на C++, но там на C++ написан рантайм, интерпретатор и JIT. Внутри себя они, возможно, где-то и используют массивы C. При этом уже в Java массив не имеет ничего общего C++, не инстанциируется через него и вообще иначе реализован, иначе аллоцируется. При этом следующий уровень абстракции, ArrayList, написан на Java.

UFO landed and left these words here

Где-то ж должно быть пересечение с системными вызовами [Dos]Alloc/Realloc/Free

Извините, вы про какие системные вызовы? В какой операционной системе? Если богомерзкой, то там LocalAlloc/LocalFree. Если в православной, то mmap. Но это не относится к языку C, это просто системные вызовы, которые можно вызывать откуда угодно. malloc/realloc/free - это уже часть стандарта C, но это уже shared libraries, которые линкуются (статически или динамически) и выполняются в user space. Внутри себя реализации malloc могут использовать системные вызовы для аллокации хипа в целом, но вряд ли вызывают их на каждый чих. И строго говоря, к массивам эти функции не имеют отношения.

JVM для объектов не использует ничего близко похожего на malloc, ибо управляемая куча принципиально иначе функционирует. И в управляемой куче, строго говоря, нет такой операции как free (даже GC внутри не "освобождает" память в хипе в том же смысле, в каком это делает free).

Массивы в Java принципиально иначе устроены. Начнём с того, что в C как таковых массивов-то и нет, есть просто арифметика указателей и синтаксический сахар, совмещающий арифметику указателей с дереференсом. В массивах Java есть длина, если полноценный vtable, ибо они тоже объекты и у них можно вызвать, например, toString или clone. При обращении к элементам массива индекс проверяется на выход за границы (если только не удалось доказать во время компиляции, что индекс не выходит), кидается исключение.

Ну вот и как можно утверждать, что массивы в JVM реализованы через массивы C? Не, ну в каком-то смысле можно так натянуть. В том, что данные массива так же расположены в памяти один за другим. Но это как утверждать, что человек - это такой же камень, потому что тоже состоит из атомов.

Небольшое уточнение. Какие там в Windows системные вызовы, никто не знает, всё вызывается через user-level DLL. Есть подозрение, что VirtualAlloc (а не LocalAlloc) реализован практически через прямой вызов в ядро, а вот всякие LocalAlloc/HeapAlloc - это по сути реализованый из коробки в dll аналог какого-нибудь jemalloc.

UFO landed and left these words here

> Ну вот и как можно утверждать, что массивы в JVM реализованы через массивы C?

я этого не утверждал

Выше было

С другой стороны, Kotlin все равно реализован на сях (ИМХО), поэтому,
мне кажется что и переписывание памяти в динамических массивах там
должно быть аналогичными,

А так же

Где-то ж должно быть пересечение с системными вызовами
[Dos]Alloc/Realloc/Free, логично это делать через Це malloc/realloc/free
ну или делая вид, что их нет - через классы Це++. Вот оно и есть в
рантайме.

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

Ваши указатели и malloc - это тоже ручка. Есть только регистры и числа в них. Остальное - от лукавого. А вообще, я сейчас даже ещё более смелое утверждение выскажу: Жаба, как и C (ИМХО) написаны на Verilog.

Вот допустим, вам потребовался объект/массив на сколько-нибудь гигабайт
памяти, вы поюзали и бросили, и далее ждете реакции допустим
пользователя до потери пульса - что будет дальше? Отдаст java системе
гигабайты?

Нет, не отдаст. Это как раз отличная иллюстрация того, что JVM не использует никак рантайм C для работы с массивами. И, кстати, для таких вот целей аллокации гигантских массивах в Java есть всяческие offheap решения (взять хотя бы тот же ByteBuffer).

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

JVM написана на C++

Хех, тоже не обязательно.
Мы как-то написали JVM на... Java. Вместо интерпретатора был baseline JIT compiler, который тоже был на... Java (правда использовал хитрые GCC конструкции для генерации binary code). И даже Memory Manager c GC был написан на... Java.

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

Под постоянным, как я понял, имеется в виду O(1) (например, в отличие от связного списка с его O(n)). Это не отменяет наличия константы, которая так или иначе связана с особенностями оборудования. Иначе тогда и сортировку можно вместо O(N * log(N)) притянуть всякое . Кстати, кэш - не единственный источник тормозов. Может быть так же

  1. Страничная адресация. Кэш страниц в ЦП + всякие особенности управления страницами в ОС

  2. Банальное обновление памяти

Fun fact

Условно есть массив на 100к элеметов типа String. В каждой ячейки массива лежит строка на 100к символов кодировки UTF-8. Сколько памяти потребуется, чтобы разместить такой массив в памяти компьютера?

Вообще-то в JVM в ячейке массива лежит указатель на строку, а не строка, как и для любого массива, содержащего не примитивы. Т.е. для 64-битной JVM это 100к 8-байтовых указателей, т.е. 800к. А строки лежат например в куче. Кроме того, длина строки не является частью сигнатуры типа для массива, поэтому при создании массива никакие 100к под один элемент не выделяются и не предполагаются, потому что эти строки уже где-то размещены к этому моменту (например в куче). И они могут быть разной длины.

Sign up to leave a comment.

Articles