Каков жизненный цикл класса Smalltalk? - PullRequest
6 голосов
/ 06 февраля 2020

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

Мои предположения являются:

  • Поскольку вы отправляете сообщения объектам и классам, они должны быть живыми и находиться в памяти, чтобы отвечать на них
  • Вы делаете объект живым (таким образом, попадая в память и слушая сообщения ) когда вы создаете его экземпляр, отправляя «новые» сообщения его классу

Хорошо, значит, объект жив от его создания до тех пор, пока сборщик мусора не убьет его или вы не отправите ему сообщение уничтожения (или, возможно, его класс)

Но как создать экземпляр класса, чтобы оживить его? Вы не можете отправить НОВОЕ сообщение метаклассу (и если да, то что такое метаметакласс для создания метакласса?) Итак, классы живы по умолчанию? Каждый класс в библиотеке smalltalk загружается в память, когда вы загружаете изображение? действительно много классов в памяти в любое время? если да, как я могу видеть классы и объекты в памяти в определенный момент времени?

Ответы [ 3 ]

6 голосов
/ 07 февраля 2020

Как описали Леандро и Берт, вы можете отправить new в метакласс. Циркулярные ссылки, которые это создает, несколько сложны для размышления, но они представляют «простоту» и «элегантность» дизайна и реализации (где красота в глазах смотрящего!). Я включил рисунок ниже, который показывает, как это работает. Обратите особое внимание на цикл между Metaclass и Metaclass class.

  • В: Итак, классы живы по умолчанию?
  • A: Да, если они существуют на изображении как объекты, то они «живы».
  • Q: Каждый класс в библиотеке smalltalk загружается в память при загрузке изображения? действительно много классов в памяти в любое время?
  • A: Да, каждый класс на изображении находится в памяти. Это много? Это может занять несколько мегабайт; это то, что находится в «базовом» изображении, которое вы получаете от провайдера диалекта. Учитывая память, используемую Chrome, Smalltalk на самом деле довольно скромный!
  • В: Если да, как я могу видеть классы и объекты в памяти в определенный момент времени?
  • A: Браузер иерархии классов показывает классы, доступные из выбранного root (обычно словарь Smalltalk). Альтернативой более низкого уровня является использование Metaclass allInstances.

. Обратите внимание также, что, хотя большинство Smalltalks имеют ClassBuilder, не все делают это (GemStone не имеет), и его свойства и поведение можно свернуть в Поведение .

Дополнительные вопросы:

  • В: Что, если я хочу уменьшенное изображение?
  • A: Доступны различные изображения Pharo, некоторые с меньшим количеством (нет *) 1045 *) и некоторые с большим. Вы также можете свободно «выгружать» ненужные пакеты и сохранять изображение. Вы также можете начать с «минимального» изображения и загружать то, что вам нужно. Да, это отличается от языков C (и других), которые начинаются пустыми при каждом создании. Основной практический эффект заключается в том, что вы ищете вещи в изображении, а не в поисках вещей вне изображения. Если вы обнаружите, что работаете в среде с ограниченным объемом 1-2 МБ, это может быть не лучшим решением для вас. Сила Smalltalk в продуктивности программистов. Сила сборки - маленький размер и скорость. Какую проблему вы пытаетесь решить?
  • В: Что такое розовый квадрат?
  • A: Все в розовом квадрате имеет название "класс", к которому добавлено. Все прямоугольники в розовом квадрате являются экземплярами метакласса (следуйте зеленым линиям типа «справа»).
  • В: Расскажите подробнее о наследовании.
  • A: В любом ОО-система, класс описывает свойства и поведение объекта. Наследование означает, что свойства и поведение суперкласса также являются частью природы объекта. Класс Person наследуется от ClassDescription напрямую через класс Object и Class. Быть экземпляром Metaclass не обеспечивает наследования. Вместо этого он предоставляет место, где описаны свойства и поведение создания класса. Итак, да, Object является экземпляром класса Object (это своего рода), который описывает, как создавать экземпляры Object. И, нет, Object не является специализацией "Object class" (наследуется от). Экземпляры объекта не знают, как создавать экземпляры объекта; это роль класса Object (фабрика).

enter image description here

4 голосов
/ 06 февраля 2020

Каждый Smalltalk имеет класс ClassBuilder, экземпляры которого предназначены для создания новых классов. A ClassBuilder делает это, сначала создав Metaclass для класса, который собирается построить, отправив сообщение класса #new на Metaclass. Затем Metaclass только что создал тот, который создает свой единственный экземпляр, используя примитив 'New'.

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

ClassBuilder заботится обо всех деталях, а также отвечает за перекомпиляцию методы экземпляра или класса, когда форма изменяется. Обратите внимание, что изменение в одном классе повлияет на все его подклассы, если таковые имеются. Таким образом, все задачи, необходимые для класса, также должны выполняться в подклассах.

Кроме того, новые классы должны быть установлены , в том смысле, что они должны быть включены в словарь Smalltalk, так что чтобы они оставались доступными и работоспособными.

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

Относительно того, как классы собирают мусор, хорошо, здесь нет ничего особенного. У Smalltalk нет сообщений для уничтожения. Объекты, на которые больше нет ссылок, становятся готовыми для сбора. Даже объекты, на которые все еще можно ссылаться, могут быть собраны, как это имеет место с двумя объектами, которые ссылаются друг на друга, но не ссылаются "извне", то есть (возможно, косвенно) из любого root.

Причина, по которой классы не являются (легко) GCed, заключается в том, что на них ссылаются из словаря Smalltalk, который является одним из корней системы. Конечно, вы можете вручную удалить класс, что означает, что он будет удален из словаря Smalltalk. В этих случаях среда поможет программисту выяснить, есть ли ссылки на Association, связывающие имя класса с объектом класса из других классов. Среда также поможет программисту проверить, есть ли в классе, который должен быть удален, экземпляры или подклассы. Кроме того, поскольку каждый класс знает свои подклассы, оттуда ссылаются на классы, поэтому суперкласс должен удалить класс из списка подклассов в рамках процесса удаления класса.

Приложение (из комментариев ниже)

Q. Кто создает класс ClassBuilder?

A. Это один из многих ) проблемы самозагрузки, которые решает каждый диалект Smalltalk. Любой Smalltalk рожден из ядра, то есть минимального набора классов и экземпляров с достаточной поддержкой для создания новых классов. В зависимости от диалекта, ClassBuilder может принадлежать или не принадлежать ядру. Если это не так, то вы все равно можете создавать классы вручную, так как единственное, что нужно, - это возможность отправить сообщение #new на Metaclass. Однако обратите внимание, что Metaclass (класс) должен быть в ядре, чтобы все это работало. Кроме того, когда вы сохраняете изображение, все объекты (включая классы и методы, которые тоже являются объектами) сохраняются на диск. После этого, когда вы загружаете изображение в память, там присутствуют те же самые объекты, и любые запущенные процессы (которые также являются объектами Smalltalk), которые выполнялись во время сохранения, возобновят работу с того места, где они были прерваны, когда произошла операция сохранения. Также обратите внимание на то, что ни один объект не «создается», он просто загружается с диска в память примитивной операцией копирования (+ возможного перемещения). Таким образом, #new не задействуется, когда вы загружаете изображение, поскольку объекты уже есть.


Q. Как создается экземпляр ClassBuilder?

A. Вы можете подумать, что он создан вручную, а затем сохранен в изображении. Итак, в следующий раз вы загрузите изображение ClassBuilder (класс) будет доступно. На самом деле, сложность ClassBuilder может потребовать нескольких итераций. Программист системы / среды выполнения может начать с создания очень простой версии, которую нужно обрабатывать с осторожностью, а затем использовать этот начальный класс для уточнения себя в дальнейших итерациях.


Q. Есть ли Metaclass для каждого класса?

A. Да.


Q. Есть ли книга для узнать о внутреннем устройстве и реализации Smalltalk?

A. Smalltalk-80 Язык и его реализация (вы можете найти его в Интернете)

3 голосов
/ 07 февраля 2020

Все классы в живой системе Smalltalk являются объектами. Некоторые были созданы долгое время go, когда система была загружена (например, некоторым объектам в Squeak более 20 лет). Память, занятая объектами, сохраняется на диске как файл «изображения», а затем возобновляется позже, когда вы «запускаете» это изображение, но объекты не создаются снова и снова.

Это не похоже на большинство других систем программирования, в которых классы и объекты создаются из исходного кода при каждом запуске программы. В Smalltalk объекты живут в памяти. Системный браузер показывает вам текстовое представление всех объектов класса в системе. Вы можете «подать» текстовое представление класса, но этот текст не является исходным исходным кодом. Исходный источник находится в объектах класса в памяти.

Чтобы создать новый класс, вы отправляете сообщение его суперклассу:

Object subclass: #NameOfClass
    instanceVariableNames: 'instVarName1 instVarName2'
    classVariableNames: 'ClassVarName1 ClassVarName2'
    poolDictionaries: ''
    category: 'Kernel-Objects'

, что вы обычно делаете, «принимая» этот шаблон в окне браузера. Это указывает существующему суперклассу (в данном случае Object) на создание нового класса. Ответ Леандро входит в детали этого. Но по сути это отправка new в Metaclass для создания нового объекта метакласса, а затем отправка new в этот метакласс для создания фактического объекта класса. Вы можете увидеть результат этого, отправив сообщение class:

'abc' class. "=> String"
'abc' class class. "=> String class"
'abc' class class class. "=> Metaclass"

Так что в этом случае 'abc' является экземпляром String, который является экземпляром String class, который является экземпляром Metaclass.

Сам объект Metaclass является частью базовой системы и был создан много лет назад go (возможно, в начале 1980-х).

Детали этого немного сложнее, но это довольно хорошее приближение к происходящему.

...