Как работает ссылка на объекты и переменные в программах? - PullRequest
0 голосов
/ 30 января 2019

Отказ от ответственности: я не очень опытный парень, и многие вопросы могут показаться глупыми или плохо сформулированными.

Я слышал о стеках и кучах и немного читал о них, но все же кое-что не понимаюне совсем понимаю:

  • Как программа находит пустую память для хранения новых переменных / объектов в физической памяти.
  • Как программа узнает, где объект начинается и где объектзаканчивается в памяти.С числовыми переменными я могу представить, что в памяти предоставлена ​​дополнительная информация, показывающая, сколько бит занимает переменная, но исправьте меня, если я ошибаюсь.
  • Это похоже на мой первый вопрос, но: когда переменная имеет значение, представленное только нулями, как программа не путает это со свободной памятью.
  • Имеет ли значение объекта null означает, что адрес объекта представляет собой набор нулей или объект указывает буквально на ничто?И если да, то как хранится «ссылка» для последующего присвоения ей адреса?

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Как программа находит пустую память для хранения новых переменных / объектов в физической памяти.

Современные операционные системы используют преобразование логических адресов.Процесс видит диапазон логических адресов - свое адресное пространство.Аппаратное обеспечение системы разбивает диапазон адресов на страницы.Размер страницы зависит от системы и часто настраивается.Операционная система управляет таблицами страниц, которые сопоставляют логические страницы с физическими фреймами страниц одинакового размера.

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

В пределах пространства пользователя и системы страницы могут быть действительными или недействительными.Недопустимая страница еще не была сопоставлена ​​с адресным пространством процесса.Большинство страниц могут быть недействительными.

Память всегда выделяется из страниц образа операционной системы.Операционная система будет иметь системные службы, которые преобразуют недопустимые страницы в допустимые страницы с сопоставлениями с физической памятью.Чтобы отобразить страницы, операционная система должна найти (или приложение должно указать) диапазон страниц, которые являются недопустимыми, а затем должна выделить физические фреймы страниц для сопоставления с этими страницами.Обратите внимание, что физические фреймы страниц не обязательно должны быть смежными с логическими страницами.

Вы упоминаете стеки и кучи.Стеки и куча - это просто память.Операционная система не может определить, является ли память стеком, кучей или чем-то еще.Библиотеки пользовательского режима для выделения памяти (например, те, которые реализуют malloc / free) выделяют память в страницах для создания кучи.Единственное, что делает эту память кучей, это то, что есть менеджер кучи, контролирующий ее.Затем менеджер кучи может выделить меньшие блоки памяти из страниц, выделенных для кучи.

Стек проще.Это просто непрерывный диапазон страниц.Обычно служба операционной системы, которая создает поток или процесс, выделяет диапазон страниц для стека и присваивает регистру указателя аппаратного стека верхний предел диапазона стека.

Как программа узнаетгде объект начинается и где объект заканчивается в памяти.С числовыми переменными я могу представить, что в памяти предоставлено несколько дополнительной информации, которая показывает программе, сколько бит занимает переменная, но исправьте меня, если я ошибаюсь.

Это зависит от того, как программаи как объект создается в памяти.Для типизированных языков компоновщик связывает переменные с адресами.Линкер также генерирует инструкцию для отображения этих адресов в адресное пространство.Для переменных стека / авто компилятор генерирует смещения от указателя на стек.Когда вызывается функция / подпрограмма, компилятор генерирует код для выделения памяти, необходимой для процедуры, что он делает простым вычитанием из указателя стека.Память освобождается простым добавлением этого значения обратно в указатель стека.

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

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

Недействительная свободная память.Доступ к свободной памяти вызывает аппаратное исключение.

Значит ли значение объекта null, что адрес объекта представляет собой набор нулей или объект указывает буквально на ничто?И если да, то как хранится «ссылка» для последующего присвоения ей адреса?

Компоновщик определяет начальное состояние адресного пространства программы пользователя.Большинство компоновщиков не отображают первую страницу (или даже более одной страницы).Эта страница недействительна.Это означает, что нулевой указатель, как вы говорите, не ссылается на абсолютно ничего.Если вы попытаетесь разыменовать нулевой указатель, вы, как правило, получите какое-то исключение нарушения прав доступа

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

0 голосов
/ 31 января 2019

Как программа находит пустую память для хранения новых переменных / объектов в физической памяти.

Физическая память управляется ОС, которая знает, какие части памяти используются процессами.и какие части бесплатны.Когда ей требуется память, программа просит операционную систему использовать части памяти.Если эта память предназначена для кучи, необходимы дополнительные операции.Операционные системы доставляют память с помощью блоков фиксированного размера, называемых страницами.Поскольку размер страницы составляет 4 КБ, если пользователь malloc s использует несколько байтов, необходимо оптимизировать использование памяти, узнать, какие части страницы используются или доступны, и отслеживать содержимое страницы после последовательных malloc и * 1007.*.Существуют конкретные структуры данных для описания используемого пространства и алгоритмы для поиска пространства, избегая при этом фрагментации.

Как программа знает, где объект начинается и где объект заканчивается в памяти.С числовыми переменными я могу представить, что в памяти предоставлено несколько дополнительной информации, которая показывает программе, сколько бит занимает переменная, но исправьте меня, если я ошибаюсь

Программа знает адрес (т.е.начало) каждой переменной.Для глобальных или статических переменных он генерируется компоновщиком, когда он помещает переменные в память.Для локальных переменных процессор имеет средства для его вычисления с учетом позиции в стеке.Для распределенных переменных он сохраняется в другой переменной (указателе) при выделении памяти.Что касается конца, это зависит от типа переменных.Для известных типов (например, int) или композиции известных типов (например, struct s) он может быть вычислен во время компиляции.В других ситуациях программа не может узнать размер объекта.Например, объявление типа int * a может описывать массив, но программа не может узнать размер массива.Программист должен отслеживать эту информацию, например, записывая количество элементов в массиве в другую переменную.

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

Программа никогда не смотрит на память, чтобы узнать, свободна она или нет.Управление им осуществляется другими средствами (см. Вопрос 1).

Значит ли значение объекта null, что адрес объекта представляет собой набор нулей или объект указывает на буквально ничто?И если да, то как хранится «ссылка» для последующего присвоения ему адреса?

Адрес никогда не является группой нулей, кроме адреса «0» памяти.Это контент, который установлен на ноль.На самом деле, невозможно прочитать или записать адрес 0. Он генерирует исключение «ошибка шины» (и, возможно, вы уже сталкивались с ним).Указание на нулевой адрес - это то же самое, что «буквальное указание на ничто» и генерирование ошибки при обнаружении в программе.Эти переменные содержат адреса других переменных (указатель).Таким образом, адрес указателя четко определен.Не может быть определено то, на что он указывает.Его можно изменить, назначив что-то указателю (например, что вернул malloc или адрес другой переменной).

...