Философия Java

Где живет хранилище


Полезно показать некоторые аспекты тог, как размещаются вещи во время работы программы, особенно, как распределяется память. Есть шесть разных вещей для хранения данных:

  • Регистры. Это самое быстрое хранилище, потому что оно существует в месте, отличном от других хранилищ: внутри процессора. Однако число регистров сильно ограничено, так что регистры резервируются компилятором в соответствии с его требованиями. Вы не имеете прямого контроля, и при этом вы не видите никакого свидетельства в вашей программе, что регистры вообще существуют.
  • Стек. Он расположен в области обычной RAM (память произвольного доступа - random-access memory), но имеет прямую поддержку процессора через указатель стека. Указатель стека перемещается вниз при создании новой памяти, и перемещается вверх при освобождении памяти. Это чрезвычайно быстрый и эффективный способ для выделения хранилища, второй после регистров. Компилятор Java должен знать во время создания программы точный размер и продолжительность жизни всех данных, которые хранятся в стеке, потому что он должен генерировать код для перемещения указателя стека вверх и вниз. Это ограничение сказывается на гибкости ваших программ, так что пока хранилище Java существует в стеке — обычно, для ссылок на объекты — объекты Java не помещаются в стек.
  • Куча. Это пул памяти общего назначения (также в области RAM), где живут объекты Java. Главная прелесть кучи, в отличие от стека, в том, что компилятору нет необходимости знать, как много места необходимо выделить из кучи для хранилища или как долго это хранилище будет оставаться в куче. Поэтому, большой плюс для гибкости при создании хранилища в куче. Когда бы вам ни понадобилось создавать объект, вы просто пишите код для его создания, используя new, а когда такой код выполняется, хранилище выделяется в куче. Конечно, вы платите за эту гибкость: это занимает больше времени при выделении хранилища в куче, чем при выделении хранилища в стеке (если бы вы могли создать объект в стеке в Java, как вы это можете в C++).
  • Статическое хранилище. “Статическое” здесь используется в смысле “в фиксированном месте” (хотя это тоже в RAM). Статическое хранилище содержит данные, которые доступны в течение всего времени выполнения программы. Вы можете использовать ключевое слово static, чтобы указать, что определенный элемент объекта - статический, но Java объект никогда не помещается в статическое хранилище.
  • Хранилище констант. Константные значения часто помещаются прямо в код программы, что является безопасным, так как они никогда не могут измениться. Иногда константы огораживают себя так, что они могут быть по выбору помещены в память только для чтения (ROM).
  • Не RAM хранилище. Если данные живут полностью вне программы, они могут существовать, пока программа не работает, вне управления программы. Два основных примера - это потоковые объекты, в которых объекты переведены в поток байтов, обычно для посылки на другую машину, и объекты представления, в которых объекты помещаются на диск, так что они сохраняют свое состояние, даже когда программа завершена. Фокус этих типов хранилищ в переводи объектов во что-то, что может существовать на другом носителе, и даже могут быть воскрешены в обычный объект в RAM, когда необходимо. Java обеспечивает поддержку для легковесной живучести, и будущие версии Java могут предлагать более полное решение для живучести.


  • Содержание раздела