Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the life cycle of a Smalltalk class?

Tags:

smalltalk

I'd like to know what is the life cycle of a class (or object), I mean, when it gets into memory and is alive answering messages until finally gets removed from memory.

My assumptions are:

  • Since you send messages to objects and classes, they must be alive and in memory to answer them
  • You make an object alive (thus getting into memory and listening to messages) when you instantiate it by sending a 'new' messages to its class

Ok, so an object is alive from its instantiation until garbage collection kills it or you send it a destroy message (or maybe its class)

But, how you instantiate a class to make it alive? you cannot send a NEW message to a kind of metaclass (and if so, what is the metametaclass to instantiate a metaclass?) So, are classes alive by default? Every class in smalltalk library is loaded into memory when you load an image? is really a lot of classes in memory at any time? if so, how can I see classes and objects in memory in certain moment in time?

like image 201
Pep Avatar asked Feb 06 '20 17:02

Pep


3 Answers

As Leandro and Bert have described, you can send new to metaclass. The circular references this creates are somewhat difficult to think about, but they represent a "simplicity" and "elegance" of design and implementation (where beauty is in the eye of the beholder!). I've included a drawing below that shows how this works. Note especially the cycle between Metaclass and Metaclass class.

  • Q: So, are classes alive by default?
  • A: Yes, if they exist in the image as objects then they are "alive."
  • Q: Every class in smalltalk library is loaded into memory when you load an image? is really a lot of classes in memory at any time?
  • A: Yes, every class in the image is in memory. Is that a lot? It may take a few megabytes; that is what is in a "base" image that you get from the dialect provider. Given the memory used by Chrome, Smalltalk is actually quite modest!
  • Q: If so, how can I see classes and objects in memory in certain moment in time?
  • A: The class hierarchy browser shows classes that are reachable from a selected root (typically the Smalltalk Dictionary). A lower-level alternative is to use Metaclass allInstances.

Note also that while most Smalltalks have ClassBuilder, not all do so (GemStone does not), and its properties and behavior can be folded into Behavior.

Additional questions:

  • Q: What if I want a smaller image?
  • A: There are various Pharo images available, some with less (no GUI) and some with more. You are also free to "unload" any unneeded packages and save your image. You can also start with a "minimal" image and load things that you need. Yes, this is different from C-based languages (and others) that start empty every time they are created. The primary practical effect is that you look for things in the image rather than looking for things outside the image. If you find that you are running in an environment where you are limited to 1-2 MB, then this might not be best for you. Smalltalk's strength is in programmer productivity. Assembly's strength is small size and speed. What problem are you trying to solve?
  • Q: What is the pink square?
  • A: Everything in the pink square has the name " class" appended to it. All the boxes in the pink square are instances of Metaclass (follow the green "is kind of" lines to the right).
  • Q: Tell me more about inheritance.
  • A: In any OO system, a class describes the properties and behaviors of an object. Inheritance means that properties and behaviors of a superclass are also part of the nature of the object. Person class inherits from ClassDescription directly through Object class and Class. Being an instance of Metaclass does not provide inheritance. Instead it provides a place where the class creation properties and behaviors are described. So, yes, Object is an instance of "Object class" (is kind of) which describes how to create instances of Object. And, no, Object is not a specialization of "Object class" (inherits from). Instances of Object do not know how to create instances of Object; that is the role of the Object class (factory).

enter image description here

like image 125
James Foster Avatar answered Oct 21 '22 10:10

James Foster


Every Smalltalk has a ClassBuilder class, whose instances have the purpose of creating new classes. A ClassBuilder does this by creating first the Metaclass for the class about to be built, sending the class message #new to Metaclass. Then it is the Metaclass just created the one that creates its sole instance using the primive 'New'.

The reason for having a ClassBuilder is that classes not only are created, they may be modified. For example, a class may change its superclass with another, or keep it but change the shape of its instances or its own shape.

The ClassBuilder takes care of all the details, and also is responsible for recompiling instance or class methods when the shape changes. Note that a change in one class will impact all its subclasses, if any. So, all the tasks required for the class need also proceed in subclasses.

In addition, new classes need to be installed, in the sense that they must be included in the Smalltalk dictionary so to keep them both accessible and alive.

Note finally that in the case of a change in shape (which can be explicit or the consequence of changing the superclass with another), existing instances of the class must be migrated so to conform to the new shape. All these tasks make the process that runs behind the scenes non-trivial. However, you can follow it from the time you send the class definition message all the way down to the 'New' primitive and to the migration of existing instances.

Regarding the way classes are garbage collected, well, there is nothing special here. Smalltalk doesn't have any destroy message. Objects that are no longer referenced become ready to be collected. Even objects which may still be referenced could be collected, as it is the case with two objects that reference each other but are not referenced from the "outside", i.e., (possibly indirectly) from any root.

The reason why classes are not (easily) GCed is because they are referenced from the Smalltalk dictionary, which is one of the roots of the system. Of course, you can manually remove a class, which means that it will be removed from the Smalltalk dictionary. In those cases the environment will assist the programmer into finding whether there are references to the Association binding the class name to the class object from other classes. The environment will also assist the programmer in checking whether the class about to be removed has instances or sublasses. Also, since every class knows its subclasses, classes are referenced from there, so the superclass needs to remove the class from its list of subclasses as part of the process of deleting the class.

Addendum (from the comments below)

Q. Who creates the ClassBuilder class?

A. This is one of the (many) bootstrapping problems that every Smalltalk dialect solves. Any Smalltalk is born from a kernel, i.e., a minimal set of classes and instances with just enough support for creating new classes. Depending on the dialect, ClassBuilder may belong or not in the kernel. If it doesn't, then you can still create classes by hand, as the only that is needed is to be able to send the #new message to Metaclass. Note however that Metaclass (the class) needs to be in the kernel for any of this to work. Also, when you save the image all the objects (including classes and methods, which are objects too), are saved to disk. Afterwards, when you load the image in memory, the very same objects are there, and any running processes (which are also Smalltalk objects) that were running at saving time, will resume where they were interrupted when the save operation took place. Note also that no object is "instantiated", they are just loaded from disk into memory in a copy (+ possible relocate) primitive operation. So, no #new is involved when you load the image as the objects are already there.


Q. How ClassBuilder gets instantiated itself?

A. You may think of it as built by hand and then saved in the image. So, the next time you load the image ClassBuilder (the class) will be available. Actually, the complexity of ClassBuilder may require several iterations. The system/runtime programmer may start by creating a very simple version of it, to be handled with care, and then use this incipient class to refine itself in further iterations.


Q. Is there a Metaclass for every class?

A. Yes.


Q. Is there any book to learn about internals and implementation of Smalltalk?

A. Smalltalk-80 The Language and its Implementation (you can find it online)

like image 25
Leandro Caniglia Avatar answered Oct 21 '22 11:10

Leandro Caniglia


All the classes in a live Smalltalk system are objects. Some were created a long time ago when the system was bootstrapped (e.g. some objects in Squeak are more than 20 years old). The memory occupied by the objects is saved to disk as an "image" file and then resumed later when you "start" that image, but the objects aren't created over and over again.

This is unlike in most other programming systems where classes and objects are created from source code every time you run a program. In Smalltalk, the objects are live in memory. The System Browser shows you a textual view of all the class objects in the system. You can "file out" a textual representation of a class but that text is not the original source code. The original source lives in the class objects in memory.

To create a new class, you send a message to its superclass:

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

which you normally do by "accepting" this template in a browser window. This instructs the existing superclass (Object in this case) to create a new class. Leandro's answer goes into the details of that. But essentially it is sending new to Metaclass to create a new metaclass object, and then sending new to that metaclass to create the actual class object. You can see the result of that by sending the class message:

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

So in this case, 'abc' is an instance of String, which is an instance of String class, which is an instance of Metaclass.

The Metaclass object itself is part of the base system and has been instantiated many many years ago (arguably in the early 1980ies).

The details of this are a little bit more complicated but this is a pretty good approximation of what is happening.

like image 31
Vanessa Freudenberg Avatar answered Oct 21 '22 10:10

Vanessa Freudenberg