And there is also #sizeInMemory sizeInMemory "Answer the number of bytes consumed by this instance including object header." | contentBytes |
contentBytes := Smalltalk wordSize. "base header" contentBytes := contentBytes + (self class instSize * Smalltalk wordSize). "instance vars" self class isVariable ifTrue:[ | bytesPerElement | "indexed elements" bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := contentBytes + (self basicSize * bytesPerElement) ]. contentBytes > 255 ifTrue: [ contentBytes := contentBytes + (2 * Smalltalk wordSize) ] ifFalse: [ self class isCompact ifFalse: [ contentBytes := contentBytes + Smalltalk wordSize] ]. ^contentBytes which is also wrong for the cases of String. For example, 'aa' sizeInMemory answers 6 but should be 8 because of alligment. If someone fixes this, I think #sizeInMemory would be correct. Cheers On Thu, Mar 15, 2012 at 6:53 PM, Eliot Miranda <eliot.mira...@gmail.com>wrote: > > Hi Niko, > > the header size calculation is also wrong. If the byte size if the > object body is > 255 bytes there needs to be an additional header size > word. So something like > > byteSizeOfBody := anObject class isBytes > ifTrue: [....] > ifFalse: [.....]. > headerSize := byteSizeOfBody > 255 > ifTrue: [12] > ifFalse: > [anObject class indexIfCompact > 0 > ifTrue: [4] > ifFalse: [8]]. > > On Wed, Mar 14, 2012 at 1:05 PM, <niko.schw...@googlemail.com> wrote: > >> Hi guys, >> >> I haven't checked if this bug exists already, so please ignore this if >> it's been reported before. >> >> Bug in WAMemoryItem: >> >> sizeOfObject: anObject >> | headerSize instanceSize variableSize | >> headerSize := anObject class indexIfCompact > 0 >> ifTrue: [ 4 ] >> ifFalse: [ 8 ]. >> instanceSize := anObject class instSize. >> variableSize := anObject class isBytes >> ifTrue: [ anObject basicSize ] >> ifFalse: [ >> anObject class isWords >> ifTrue: [ Smalltalk wordSize * anObject >> basicSize ] >> ifFalse: [ Smalltalk wordSize * anObject >> basicSize // 2 ] ]. >> ^ headerSize + instanceSize + variableSize >> >> >> In this snippet, the units that are added together in the last line are >> of different units. >> >> instanceSize is in unit "number of machine words", whereas variableSize >> and headerSize are in unit "bytes". >> >> >> The method is fixed here: >> >> sizeOfObject: anObject >> | headerSize instanceSize variableSize | >> headerSize := anObject class indexIfCompact > 0 >> ifTrue: [ 4 ] >> ifFalse: [ 8 ]. >> instanceSize := anObject class instSize * Smalltalk wordSize. >> variableSize := anObject class isBytes >> ifTrue: [ anObject basicSize ] >> ifFalse: [ >> anObject class isWords >> ifTrue: [ Smalltalk wordSize * anObject >> basicSize ] >> ifFalse: [ Smalltalk wordSize * anObject >> basicSize // 2 ] ]. >> ^ headerSize + instanceSize + variableSize >> >> >> >> Example: >> >> |m| >> dict := Dictionary new. >> m := WAMemory new. dict traverseWithMemory: m seen: IdentitySet new. >> m totalSize >> >> This will incorrectly spit out 10, but should return 16, on a 32 bit VM. >> >> Niko >> >> -- >> http://scg.unibe.ch/staff/Schwarz >> twitter.com/nes1983 >> Tel: +41786126354 >> >> >> > > > -- > best, > Eliot > > > -- Mariano http://marianopeck.wordpress.com