Saving memory in Smalltalk
Return to home page
Comments Loading...
2004-12-18

We all know that most of the memory in a Smalltalk image is taken up by Instances of objects. A large saving can be made if we stop creating new instances of classes. This has other advantages too. It makes Smalltalk more like Self.

Where you would normally write code like:

newInstance := MyClass new.

We would now write code like:

newInstance := Smalltalk defineClass: #MyClassNew1
	superclass: #{Smalltalk.MyClass}
	indexedType: #none
	private: false
	instanceVariableNames: ''
	classInstanceVariablenames: ''
	imports: ''
	category: 'None'

The advantages are obvious! Not only can we save space by not making lots of instances, but we can also save space by sharing instance variables.

"Shared Variables" as they are called, can be re-used across objects in the system. This is an amazing breakthrough. Also, instead of using instanceVariables, more space is saved by using classInstanceVariables.

But it gets better. In languages like Self, you can change the behaviour of your instances. In fact, in a language like Self, you only ever care about what an object is 'of'. In Smalltalk, we not only have to worry about an instances class, but what that class inherits from too. By not using instances, both of those concerns are consolidated in to your superclass.

Now we can add behaviour to our new Object, because it gets the same priviledges as any other class.

We can wrap up the creation too - replacing that horrid new - to give us new objects:

new
	^Smalltalk defineClass: (self name, self nextObjectId printString) asSymbol
		superclass: self
		indexedType: #none
		private: false
		instanceVariableNames: ''
		classInstanceVariablenames: ''
		imports: ''
		category: 'None'

Notice the lack of 'self class' code. This is considered good practice - before developers had to worry about the 'class side' and the 'instance side' - now it's much simpler. We now never have to worry about singletons again either!. What's also amazing is that for some reason, the garbage collector doesn't have to do as much work. This gives us even more CPU time to play with. Benefits all-round.

We don't need an inspector any more either. The Refactoring Browser conveniently shows us all our Objects "As it Should!" and lets us change code, copy code and see our values. It even has a special tab for Shared Variables. We can now simplify the RB by removing the 'instance' side of things to save all that nasty confusion and memory wastage.

Lets go to NameSpaceItemTabNavigatorPart and change the method #defaultTabDescriptions. Remove the first one! Remove the one descripting Instances - yuck.

Now that that's gone, it's time to save some memory. The next step is tricky, but it will reduce memory consumption by a lot.

Object allSubclasses do: [:aClass |
	aClass allInstances do: [:anInstance |
		anInstance oneWayBecome: nil]].

This will remove all the instances from your system. Once that has completed, you are now free to use the new #new behaviour - put it on Object as an Override. Your Smalltalk will run faster and you'll save memory and you'll have all the wonderful benefits of a prototyped language - and now you truelly do have a 'Class Based Language' and an 'Object Oriented Language'.