a short ImageSegment howto

goran.hultgren at bluefish.se goran.hultgren at bluefish.se
Mon Jan 28 16:58:25 UTC 2002


I lifted this thread into the Squeak dev list instead of
Squeakfoundation.

Bijan Parsia <bparsia at email.unc.edu> wrote:
> On Mon, 28 Jan 2002 goran.hultgren at bluefish.se wrote:
> > Bijan Parsia <bparsia at email.unc.edu> wrote:
> [snipped violent agreement]
> > > <CSOTD>"OK, I'm finalling doing one of these. This uses ImageSegments to 
> > > help figure out memory consumption of your objects:"
> > > 
> > > String streamContents: [:strm |
> > > 		(ImageSegment new copyFromRootsForExport: Browser allInstances)
> > > 					printSpaceAnalysisOn: strm]
> > > </CSOTD>
> > 
> > Hehe! Go, go...
> 
> Hmm. Now that I've posted this, I can ask: What *exactly* does it
> analyze? How deep does it go?

Ok, an ImageSegment contains all objects that are ONLY reachable from
it's roots.
It uses the GC algorithms in a smart way by essentially withholding the
roots in question
and doing a mark from all other roots (globals). This will leave the
objects in memory
that are only reachable from your segmentroots unmarked.

> Also, if I want to dump and image segment to disk and read it back in
> *not* as a project, how do I do it? Is it worth doing?

Sure! There are basically two ways of using an ImageSegment. One can be
used for "object swapping" like this,
below is a method from an "account" object I have:

swapOut
	"Swaps out this object using an ImageSegment.
	Returns the ImageSegment created. Each reference to me or into
	any of my parts will be turned into an ImageSegmentRootStub
	which acts as an autoloading proxy thus bringing me back in
	at first access. The stubs know the ImageSegment so it does not need
	to be remembered. The ImageSegment can be brought in
	directly by calling #install on it."

	| is myParent |
	myParent _ parent.
	parent _ nil.
	is _ ImageSegment new.
	is copyFromRoots: (Array with: self) sizeHint: 500000 areUnique: true.
	is segmentName: 'account', id fullPrintString.
	is extract; writeToFile.
	parent _ myParent.
	^is

This would "swap out" the object and replace all references with
autoloading stubs. It works like a charm!
And especially loading it back in is FAST.

Here is some code for using ImageSegments for export into possibly other
images that I recently whipped up:

checkpoint
	"Export me using an ImageSegment. Return nil on fail.
	This is used for checkpointing the account on disk
	in a form that can be brought into an independent image.
	We do not overwrite older versions - when the image does a
	snapshot it can purge old checkpoints."

	| is fname myParent dir stream |
	myParent _ parent.
	lastCheckPoint _ TimeStamp current.
	dir _ self dir.
	fname _ dir nextNameFor: self fileName extension: self
fileNameExtension.
	stream _ dir newFileNamed: fname.
	[ parent _ nil.
	is _ ImageSegment new.
	is copyFromRoots: (Array with: self) sizeHint: 1000000 areUnique: true.
	is writeForExportOn: stream ]
		ifError: [parent _ myParent. ^nil].
	parent _ myParent.
	^is

The method above nils out a parent pointer but that is just to "make
sure". The sizeHint is good to set high because otherwise there will be
numerous "tries" when dumping large structures and that takes a lot of
time.
The writeForExportOn: method wraps the ImageSegment in a ReferenceStream
in order to gracefully deal with the outpointers.

This needs a new simple method in ImageSegment to work:

writeForExportOn: fileStream
	"Write the segment on the disk with all info needed to reconstruct it
in a new image.  For export.  Out pointers are encoded as normal objects
on the disk."

	| temp |
	state = #activeCopy ifFalse: [self error: 'wrong state'].
	temp _ endMarker.
	endMarker _ nil.
	fileStream fileOutClass: nil andObject: self.
		"remember extra structures.  Note class names."
	endMarker _ temp

> I managed to dump a segment, but I'm completely unclear how to read one
> back in. Is there any point to using an ImageSegment over a
> ReferenceStream?

I would guess they are much faster.
 
> (Don't have another CSOTD handy :))

It's hard work!

regards, Göran

PS. <CSOTD>"Wasn't the above enough? Come on!"</CSOTD>



More information about the Squeak-dev mailing list