[Pharo-project] is it possible to know the memory occupation (bytes) of an object?
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes. Is this possible ? if true, how ? I would like to do it from both sides: image and VM. I checked both but I didn't find anything. Thanks in advance Mariano
I once sent some code to the mailing list (search for thread named "Size of objects"). We should add this to the image. I think I named it #sizeInMemory. Adrian On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Tue, Apr 27, 2010 at 12:45 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
I once sent some code to the mailing list (search for thread named "Size of objects").
Thanks Adrian...I couldn't find it. Can you forward it to me please? or just send me the code...
We should add this to the image. I think I named it #sizeInMemory.
There are only changes to the image side ? or the vm also ? Thanks Mariano
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Its a simple method in Object: Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)" | headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize Please also note the other mail I sent to this thread. Adrian On Apr 27, 2010, at 13:16 , Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 12:45 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
I once sent some code to the mailing list (search for thread named "Size of objects").
Thanks Adrian...I couldn't find it. Can you forward it to me please? or just send me the code...
We should add this to the image. I think I named it #sizeInMemory.
There are only changes to the image side ? or the vm also ?
Thanks
Mariano
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Hi folks. Sorry for the cross post this time, but I guess it is worth. In Pharo we were trying to get a way to know the amount of memory (bytes) that an objects is occupying in RAM memory. For such purpose, Adrian posposed the following method: Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)" | headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize Do you think this is correct for all cases? Is there a way to know this but from the VM side also ? how ? I really need it from the VM side :( but I have no idea how to do it. Thanks Mariano ---------- Forwarded message ---------- From: Adrian Lienhard <adi@netstyle.ch> Date: Tue, Apr 27, 2010 at 1:19 PM Subject: Re: [Pharo-project] is it possible to know the memory occupation (bytes) of an object? To: Pharo-project@lists.gforge.inria.fr Its a simple method in Object: Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)" | headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize Please also note the other mail I sent to this thread. Adrian On Apr 27, 2010, at 13:16 , Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 12:45 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
I once sent some code to the mailing list (search for thread named "Size of objects").
Thanks Adrian...I couldn't find it. Can you forward it to me please? or just send me the code...
We should add this to the image. I think I named it #sizeInMemory.
There are only changes to the image side ? or the vm also ?
Thanks
Mariano
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 4/28/2010 11:00 AM, Mariano Martinez Peck wrote:
Hi folks. Sorry for the cross post this time, but I guess it is worth.
In Pharo we were trying to get a way to know the amount of memory (bytes) that an objects is occupying in RAM memory.
For such purpose, Adrian posposed the following method:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
Do you think this is correct for all cases?
It's close but not entirely correct. The computation needs to include the extra header word for "large" instances (> 255 bytes). Squeak has three possible header sizes: 1 header word - used by compact classes 2 header words - used by regular classes 3 header words - used by "large" instances BTW, SpaceTally>>spaceForInstancesOf:withInstanceCount: has the correct computation (except for 64 bit :-)
Is there a way to know this but from the VM side also ? how ? I really need it from the VM side :( but I have no idea how to do it.
It's easy to do in the VM, just use this: primitiveByteSize "Answers the number of bytes the receiver occupies" | nbytes| self export: true. oop := self popStack. nbytes := (self sizeBitsOf: oop) + (self extraHeaderBytes: oop). self pushInteger: nbytes. Cheers, - Andreas
On Wed, Apr 28, 2010 at 11:26:54AM -0700, Andreas Raab wrote:
BTW, SpaceTally>>spaceForInstancesOf:withInstanceCount: has the correct computation (except for 64 bit :-)
Somebody should do something about that one of these days, so I put it on Mantis: http://bugs.squeak.org/view.php?id=7518 Dave
It's close but not entirely correct. The computation needs to include the extra header word for "large" instances (> 255 bytes). Squeak has three possible header sizes:
1 header word - used by compact classes 2 header words - used by regular classes 3 header words - used by "large" instances
BTW, SpaceTally>>spaceForInstancesOf:withInstanceCount: has the correct computation (except for 64 bit :-)
Ok, perfect. Thanks :)
Is there a way to know this
but from the VM side also ? how ? I really need it from the VM side :( but I have no idea how to do it.
It's easy to do in the VM, just use this:
primitiveByteSize "Answers the number of bytes the receiver occupies"
| nbytes| self export: true. oop := self popStack. nbytes := (self sizeBitsOf: oop) + (self extraHeaderBytes: oop). self pushInteger: nbytes.
I tried this and seems to work ok. I don't really need a primitive but an internal method that is called by a primitive. So, I did something like this: internalByteSize: anOop "Answers the number of bytes the receiver occupies" | nbytes| self inline: true. nbytes := (self sizeBitsOf: anOop) + (self extraHeaderBytes: anOop). ^ nbytes. and then I call it like this for example: oop := self firstAccessibleObject. [oop = nil] whileFalse: [ (self isIntegerObject: oop) ifFalse: [ size := self internalByteSize: oop. ......] oop := self accessibleObjectAfter: oop. ]. but internalByteSize ALWAYS return me the same value...do you know what can be wrong ? Thanks in advance Mariano
Ok, the problem was that I was doing: usedMemory := usedMemory + self internalByteSize: oop. that didn't work and always answered me the same number. Now, I had to do this: usedMemory := usedMemory + (self internalByteSize: oop). I don't understand why. Thanks Mariano On Thu, Apr 29, 2010 at 3:22 PM, Mariano Martinez Peck < marianopeck@gmail.com> wrote:
It's close but not entirely correct. The computation needs to include the extra header word for "large" instances (> 255 bytes). Squeak has three possible header sizes:
1 header word - used by compact classes 2 header words - used by regular classes 3 header words - used by "large" instances
BTW, SpaceTally>>spaceForInstancesOf:withInstanceCount: has the correct computation (except for 64 bit :-)
Ok, perfect. Thanks :)
Is there a way to know this
but from the VM side also ? how ? I really need it from the VM side :( but I have no idea how to do it.
It's easy to do in the VM, just use this:
primitiveByteSize "Answers the number of bytes the receiver occupies"
| nbytes| self export: true. oop := self popStack. nbytes := (self sizeBitsOf: oop) + (self extraHeaderBytes: oop). self pushInteger: nbytes.
I tried this and seems to work ok. I don't really need a primitive but an internal method that is called by a primitive. So, I did something like this:
internalByteSize: anOop
"Answers the number of bytes the receiver occupies" | nbytes| self inline: true. nbytes := (self sizeBitsOf: anOop) + (self extraHeaderBytes: anOop). ^ nbytes.
and then I call it like this for example:
oop := self firstAccessibleObject. [oop = nil] whileFalse: [ (self isIntegerObject: oop) ifFalse: [ size := self internalByteSize: oop. ......] oop := self accessibleObjectAfter: oop. ].
but internalByteSize ALWAYS return me the same value...do you know what can be wrong ?
Thanks in advance
Mariano
On 4/29/2010 6:22 AM, Mariano Martinez Peck wrote:
and then I call it like this for example:
oop := self firstAccessibleObject. [oop = nil] whileFalse: [ (self isIntegerObject: oop) ifFalse: [ size := self internalByteSize: oop. ......] oop := self accessibleObjectAfter: oop. ].
Do you realize that this simple computes the used memory which is information that's directly accessible via the vm parameters? I don't recall which one but you might want to look at these to see if they already have what you need. Cheers, - Andreas
On Thu, Apr 29, 2010 at 6:00 PM, Andreas Raab <andreas.raab@gmx.de> wrote:
On 4/29/2010 6:22 AM, Mariano Martinez Peck wrote:
and then I call it like this for example:
oop := self firstAccessibleObject. [oop = nil] whileFalse: [ (self isIntegerObject: oop) ifFalse: [ size := self internalByteSize: oop. ......] oop := self accessibleObjectAfter: oop. ].
Do you realize that this simple computes the used memory which is information that's directly accessible via the vm parameters? I don't recall which one but you might want to look at these to see if they already have what you need.
Thanks Andreas. I guess I should have explained my situation. Basically, what I was trying to do (and I did at the end) is to use the last free bit of the object header to use it to detect used and unused objects. I modified the VM so that when an object receives a message, it enables such bit. I also have primitives to mark and unmark all objects. I am not sure what I will do then with the unused objects, but for the moment, I just wanted to get numbers. Statistics. So, for example I wanted to know how many objects were with the bit on and how many with the bit off. Also the amount of memory those objects represents. The method is: primitiveGetStadistics | oop usedCount unusedCount results usedMemory unusedMemory usedCountOop unusedCountOop usedMemoryOop unusedMemoryOop | usedCount := unusedCount := 0. usedMemory := unusedMemory := 0. self print: 'Start to check objects'; cr. oop := self firstAccessibleObject. [oop = nil] whileFalse: [ (self isIntegerObject: oop) ifFalse: [ (self internalIsUsed: oop) ifTrue: [ usedCount := usedCount +1. usedMemory := usedMemory + (self internalByteSize: oop). ] ifFalse: [ unusedCount := unusedCount +1. unusedMemory := unusedMemory + (self internalByteSize: oop). ]. ]. oop := self accessibleObjectAfter: oop. ]. self print: 'Finish to check objects'; cr. self print: 'Push stadistics'; cr. self pushRemappableOop: (self instantiateClass: (self classArray) indexableSize: 4). self pushRemappableOop: (self positive64BitIntegerFor: usedCount). self pushRemappableOop: (self positive64BitIntegerFor: usedMemory). self pushRemappableOop: (self positive64BitIntegerFor: unusedCount). self pushRemappableOop: (self positive64BitIntegerFor: unusedMemory). self print: 'Pop stadistics'; cr. unusedMemoryOop := self popRemappableOop. unusedCountOop := self popRemappableOop. usedMemoryOop := self popRemappableOop. usedCountOop := self popRemappableOop. results := self popRemappableOop. self print: 'Write stadistics in array'; cr. self storePointer: 0 ofObject: results withValue: usedCountOop. self storePointer: 1 ofObject: results withValue: unusedCountOop. self storePointer: 2 ofObject: results withValue: usedMemoryOop. self storePointer: 3 ofObject: results withValue: unusedMemoryOop. self print: 'Push result array in stadistics'; cr. self pop: 1 thenPush: results. And as you may guess, internalIsUsed: oop self inline: true. ^((self baseHeader: oop) bitAnd: UsedObjectBit) ~= 0 So then, from the image side, I can get statistics at certain point, and get something like the attached screenshot. Thanks. Mariano
Cheers, - Andreas
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Tue, Apr 27, 2010 at 1:19 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
Its a simple method in Object:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
Hi Adrian. Sorry for returning to this thread. I am trying to contemplate all the cases. I was looking at SpaceTally and I found that maybe a better implementation could be something like this: Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact instVarBytes bytesPerElement headerBytes total contentBytes | isCompact := self class indexIfCompact > 0. instVarBytes := self class instSize * 4. self class isVariable ifTrue: [ bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. total := 0. contentBytes := instVarBytes + (self basicSize * bytesPerElement). headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. total := headerBytes + contentBytes. ^ total] ifFalse: [ headerBytes := instVarBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes ]. I guess I did some mistake but if we can arrive to a good implementation it would be really cool. Thanks mariano
Please also note the other mail I sent to this thread.
Adrian
On Apr 27, 2010, at 13:16 , Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 12:45 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
I once sent some code to the mailing list (search for thread named "Size of objects").
Thanks Adrian...I couldn't find it. Can you forward it to me please? or just send me the code...
We should add this to the image. I think I named it #sizeInMemory.
There are only changes to the image side ? or the vm also ?
Thanks
Mariano
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 21.09.2010 20:47, Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 1:19 PM, Adrian Lienhard <adi@netstyle.ch <mailto:adi@netstyle.ch>> wrote:
Its a simple method in Object:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
Hi Adrian. Sorry for returning to this thread. I am trying to contemplate all the cases.
I was looking at SpaceTally and I found that maybe a better implementation could be something like this:
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header."
| isCompact instVarBytes bytesPerElement headerBytes total contentBytes | isCompact := self class indexIfCompact > 0. instVarBytes := self class instSize * 4. self class isVariable ifTrue: [ bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. total := 0. contentBytes := instVarBytes + (self basicSize * bytesPerElement). headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. total := headerBytes + contentBytes. ^ total] ifFalse: [ headerBytes := instVarBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes ].
I guess I did some mistake but if we can arrive to a good implementation it would be really cool.
Thanks
mariano
Please, at least do some refactoring :) Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact headerBytes contentBytes | isCompact := self class indexIfCompact > 0. contentBytes := self class instSize * Smalltalk wordSize. "inst vars" self class isVariable ifTrue: [ |bytesPerElement| bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := contentBytes + (self basicSize * bytesPerElement)]. headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes Also, in a 64-bit image, I suspect you may have to make a distinction between class isWords as well. ie: self class isBytes ifTrue: [1] ifFalse: [self class isWords ifTrue: [4] ifFalse: [Smalltalk wordSize]] Cheers, Henry
2010/9/21 Henrik Sperre Johansen <henrik.s.johansen@veloxit.no>
On 21.09.2010 20:47, Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 1:19 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
Its a simple method in Object:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
^ headerSize + contentBytes
:) Thanks Henry....so do you think we can integrate this? Adrian?
Hi Adrian. Sorry for returning to this thread. I am trying to contemplate all the cases.
I was looking at SpaceTally and I found that maybe a better implementation could be something like this:
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header."
| isCompact instVarBytes bytesPerElement headerBytes total contentBytes | isCompact := self class indexIfCompact > 0. instVarBytes := self class instSize * 4. self class isVariable ifTrue: [ bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. total := 0. contentBytes := instVarBytes + (self basicSize * bytesPerElement). headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. total := headerBytes + contentBytes. ^ total] ifFalse: [ headerBytes := instVarBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes ].
I guess I did some mistake but if we can arrive to a good implementation it would be really cool.
Thanks
mariano
Please, at least do some refactoring :)
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact headerBytes contentBytes |
isCompact := self class indexIfCompact > 0. contentBytes := self class instSize * Smalltalk wordSize. "inst vars"
self class isVariable ifTrue: [ |bytesPerElement| bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := contentBytes + (self basicSize * bytesPerElement)].
headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes
Also, in a 64-bit image, I suspect you may have to make a distinction between class isWords as well. ie: self class isBytes ifTrue: [1] ifFalse: [self class isWords ifTrue: [4] ifFalse: [Smalltalk wordSize]]
Cheers, Henry
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Some notes: - What should be answered for small ints? 1 sizeInMemory -->8. That's wrong. Shouldn't this answer 0? - In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something? - Please remove the inline comment "inst vars"; if a comment is needed it should go into the main comment. Adrian On Sep 21, 2010, at 22:14 , Mariano Martinez Peck wrote:
2010/9/21 Henrik Sperre Johansen <henrik.s.johansen@veloxit.no>
On 21.09.2010 20:47, Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 1:19 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
Its a simple method in Object:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
^ headerSize + contentBytes
:)
Thanks Henry....so do you think we can integrate this?
Adrian?
Hi Adrian. Sorry for returning to this thread. I am trying to contemplate all the cases.
I was looking at SpaceTally and I found that maybe a better implementation could be something like this:
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header."
| isCompact instVarBytes bytesPerElement headerBytes total contentBytes | isCompact := self class indexIfCompact > 0. instVarBytes := self class instSize * 4. self class isVariable ifTrue: [ bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. total := 0. contentBytes := instVarBytes + (self basicSize * bytesPerElement). headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. total := headerBytes + contentBytes. ^ total] ifFalse: [ headerBytes := instVarBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes ].
I guess I did some mistake but if we can arrive to a good implementation it would be really cool.
Thanks
mariano
Please, at least do some refactoring :)
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact headerBytes contentBytes |
isCompact := self class indexIfCompact > 0. contentBytes := self class instSize * Smalltalk wordSize. "inst vars"
self class isVariable ifTrue: [ |bytesPerElement| bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := contentBytes + (self basicSize * bytesPerElement)].
headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes
Also, in a 64-bit image, I suspect you may have to make a distinction between class isWords as well. ie: self class isBytes ifTrue: [1] ifFalse: [self class isWords ifTrue: [4] ifFalse: [Smalltalk wordSize]]
Cheers, Henry
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Thanks Adrian for the feedback. I agree with your comments. What about this now: sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact headerBytes contentBytes | (self isMemberOf: SmallInteger) ifTrue: [^0]. self class isVariable ifTrue: [ | bytesPerElement | bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := (self basicSize * bytesPerElement).] ifFalse: [ contentBytes := self class instSize * Smalltalk wordSize.]. isCompact := self class indexIfCompact > 0. headerBytes := contentBytes > 255 ifTrue: [3 * Smalltalk wordSize] ifFalse: [isCompact ifTrue: [Smalltalk wordSize] ifFalse: [2 * Smalltalk wordSize]]. ^ headerBytes + contentBytes is it better? cheers Mariano On Wed, Sep 22, 2010 at 9:59 AM, Adrian Lienhard <adi@netstyle.ch> wrote:
Some notes:
- What should be answered for small ints? 1 sizeInMemory -->8. That's wrong. Shouldn't this answer 0?
- In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something?
- Please remove the inline comment "inst vars"; if a comment is needed it should go into the main comment.
Adrian
On Sep 21, 2010, at 22:14 , Mariano Martinez Peck wrote:
2010/9/21 Henrik Sperre Johansen <henrik.s.johansen@veloxit.no>
On 21.09.2010 20:47, Mariano Martinez Peck wrote:
On Tue, Apr 27, 2010 at 1:19 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
Its a simple method in Object:
Object>>sizeInMemory "Returns the number of bytes used by this object in memory (including its header)"
| headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := (self class isVariable ifFalse: [ self class instSize * Smalltalk wordSize ] ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize
^ headerSize + contentBytes
:)
Thanks Henry....so do you think we can integrate this?
Adrian?
Hi Adrian. Sorry for returning to this thread. I am trying to
contemplate
all the cases.
I was looking at SpaceTally and I found that maybe a better implementation could be something like this:
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header."
| isCompact instVarBytes bytesPerElement headerBytes total contentBytes | isCompact := self class indexIfCompact > 0. instVarBytes := self class instSize * 4. self class isVariable ifTrue: [ bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. total := 0. contentBytes := instVarBytes + (self basicSize * bytesPerElement). headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. total := headerBytes + contentBytes. ^ total] ifFalse: [ headerBytes := instVarBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes ].
I guess I did some mistake but if we can arrive to a good implementation it would be really cool.
Thanks
mariano
Please, at least do some refactoring :)
Object >> sizeInMemory "Answer the number of bytes consumed by this instance including object header." | isCompact headerBytes contentBytes |
isCompact := self class indexIfCompact > 0. contentBytes := self class instSize * Smalltalk wordSize. "inst vars"
self class isVariable ifTrue: [ |bytesPerElement| bytesPerElement := self class isBytes ifTrue: [1] ifFalse: [4]. contentBytes := contentBytes + (self basicSize * bytesPerElement)].
headerBytes := contentBytes > 255 ifTrue: [12] ifFalse: [isCompact ifTrue: [4] ifFalse: [8]]. ^ headerBytes + instVarBytes
Also, in a 64-bit image, I suspect you may have to make a distinction between class isWords as well. ie: self class isBytes ifTrue: [1] ifFalse: [self class isWords ifTrue: [4] ifFalse: [Smalltalk wordSize]]
Cheers, Henry
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Sep 22, 2010, at 9:59 40AM, Adrian Lienhard wrote:
Some notes:
- What should be answered for small ints? 1 sizeInMemory -->8. That's wrong. Shouldn't this answer 0?
Philosophical question really, imo both 4 (Again, in 32bit images at least) and 0 would be "correct" answers in their own ways. 8 is definitely wrong though :) The method comment should probably highlight which definition is used.
- In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something?
You can have instance variables in variable classes: ArrayedCollection variableSubclass: #TallyArray instanceVariableNames: 'tally' classVariableNames: '' poolDictionaries: '' category: 'Collections-Arrayed' TallyArray instSize 1 (TallyArray new: 5) basicSize 5 Sure, they're not used very often in Squeak/Pharo since become: is so slow, but there's no theoretical reason why you can't for example implement Set as a variable subclass with a tally inst var.
- Please remove the inline comment "inst vars"; if a comment is needed it should go into the main comment.
I agree, should be self-explanatory. Cheers, Henry
On Wed, Sep 22, 2010 at 12:12 PM, Henrik Johansen < henrik.s.johansen@veloxit.no> wrote:
On Sep 22, 2010, at 9:59 40AM, Adrian Lienhard wrote:
Some notes:
- What should be answered for small ints? 1 sizeInMemory -->8. That's wrong. Shouldn't this answer 0?
Philosophical question really, imo both 4 (Again, in 32bit images at least) and 0 would be "correct" answers in their own ways. 8 is definitely wrong though :) The method comment should probably highlight which definition is used.
At the beginning I also thought to have 4, instead of 0. The problem is that if you put 4 and you have an object with and instVar that it is a SmallInteger, it will be counted twice, when actually it is only one. That's why I thoguht 0 was better, since I want the really occupated memory. On the other hand, if you do "4 sizeInMemory" and see zero, I have to admit it is a litlte confusing. The problem is that if I do for example: Class >> spaceForInstances | totalSize | totalSize := 0. self allInstancesDo: [ :inst | totalSize := totalSize + inst sizeInMemory. ]. ^ totalSize SmallInteger spaceForInstances ->> 0 So I don't know...maybe we have to answer 4 instead of 0? Adrian what do you think?
- In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something? You can have instance variables in variable classes:
ArrayedCollection variableSubclass: #TallyArray instanceVariableNames: 'tally' classVariableNames: '' poolDictionaries: '' category: 'Collections-Arrayed'
TallyArray instSize 1 (TallyArray new: 5) basicSize 5
Sure, they're not used very often in Squeak/Pharo since become: is so slow, but there's no theoretical reason why you can't for example implement Set as a variable subclass with a tally inst var.
- Please remove the inline comment "inst vars"; if a comment is needed it
should go into the main comment. I agree, should be self-explanatory.
Cheers, Henry _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Wed, Sep 22, 2010 at 12:34 PM, Mariano Martinez Peck < marianopeck@gmail.com> wrote:
On Wed, Sep 22, 2010 at 12:12 PM, Henrik Johansen < henrik.s.johansen@veloxit.no> wrote:
On Sep 22, 2010, at 9:59 40AM, Adrian Lienhard wrote:
Some notes:
- What should be answered for small ints? 1 sizeInMemory -->8. That's wrong. Shouldn't this answer 0?
Philosophical question really, imo both 4 (Again, in 32bit images at least) and 0 would be "correct" answers in their own ways. 8 is definitely wrong though :) The method comment should probably highlight which definition is used.
So....what should we consider for SmallInteger ? 4 bytes or 0 bytes? I would like to compute the really used memory. thanks mariano
At the beginning I also thought to have 4, instead of 0. The problem is that if you put 4 and you have an object with and instVar that it is a SmallInteger, it will be counted twice, when actually it is only one. That's why I thoguht 0 was better, since I want the really occupated memory. On the other hand, if you do "4 sizeInMemory" and see zero, I have to admit it is a litlte confusing.
The problem is that if I do for example:
Class >> spaceForInstances | totalSize | totalSize := 0. self allInstancesDo: [ :inst | totalSize := totalSize + inst sizeInMemory. ]. ^ totalSize
SmallInteger spaceForInstances ->> 0
So I don't know...maybe we have to answer 4 instead of 0?
Adrian what do you think?
- In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something? You can have instance variables in variable classes:
ArrayedCollection variableSubclass: #TallyArray instanceVariableNames: 'tally' classVariableNames: '' poolDictionaries: '' category: 'Collections-Arrayed'
TallyArray instSize 1 (TallyArray new: 5) basicSize 5
Sure, they're not used very often in Squeak/Pharo since become: is so slow, but there's no theoretical reason why you can't for example implement Set as a variable subclass with a tally inst var.
- Please remove the inline comment "inst vars"; if a comment is needed
it should go into the main comment. I agree, should be self-explanatory.
Cheers, Henry _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Sep 22, 2010, at 12:12 , Henrik Johansen wrote:
- In the line contentBytes := contentBytes + (self basicSize * bytesPerElement), why is contentBytes added because it should be always 0 because self class instSize should return 0 in case of variable classes. Or do I miss something? You can have instance variables in variable classes:
Yes, of course; I forgot this case. Adrian
BTW, Lukas had pointed out that my implementation is incomplete. So before integrating we should make sure the implementation covers all cases. Adrian Begin forwarded message:
From: "Lukas Renggli" <renggli@gmail.com> Date: October 21, 2008 6:28:32 PM GMT+02:00 To: "Pharo Development" <pharo-project@lists.gforge.inria.fr> Subject: Re: [Pharo-project] Size of objects Reply-To: Pharo Development <pharo-project@lists.gforge.inria.fr>
BTW, I think that would be a meaningful addition. Could somebody quickly check the method to verify that I didn't do any miscalculation?
The only problem I see is that variable objects might also have inst-vars. So you need to count the
self class instSize * Smalltalk wordSize
part in any case.
Lukas
On Apr 27, 2010, at 12:45 , Adrian Lienhard wrote:
I once sent some code to the mailing list (search for thread named "Size of objects"). We should add this to the image. I think I named it #sizeInMemory.
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Tue, Apr 27, 2010 at 1:17 PM, Adrian Lienhard <adi@netstyle.ch> wrote:
BTW, Lukas had pointed out that my implementation is incomplete. So before integrating we should make sure the implementation covers all cases.
Adrian
Begin forwarded message:
From: "Lukas Renggli" <renggli@gmail.com> Date: October 21, 2008 6:28:32 PM GMT+02:00 To: "Pharo Development" <pharo-project@lists.gforge.inria.fr> Subject: Re: [Pharo-project] Size of objects Reply-To: Pharo Development <pharo-project@lists.gforge.inria.fr>
BTW, I think that would be a meaningful addition. Could somebody quickly check the method to verify that I didn't do any miscalculation?
The only problem I see is that variable objects might also have inst-vars. So you need to count the
self class instSize * Smalltalk wordSize
I am not sure if I understood. Then the method should be something like this: sizeInMemory "Returns the number of bytes used by this object in memory (including its header)" | headerSize instanceSize | headerSize := (self class indexIfCompact > 0 ifTrue: [ 4 ] ifFalse: [ 8 ]). instanceSize := self class instSize * Smalltalk wordSize. instanceSize := instanceSize + (self class isVariable ifTrue: [ (self basicSize * (self class isBytes ifTrue: [ 1 ] ifFalse: [ Smalltalk wordSize ])) ]). ^ headerSize + instanceSize ? Thanks Mariano
part in any case.
Lukas
On Apr 27, 2010, at 12:45 , Adrian Lienhard wrote:
I once sent some code to the mailing list (search for thread named "Size of objects"). We should add this to the image. I think I named it #sizeInMemory.
Adrian
On Apr 27, 2010, at 12:03 , Mariano Martinez Peck wrote:
Hi. I don't know if "memory occupation" is the better name. I just want to know the amount of memory that an object is occupying in RAM. I mean, the amount of bytes.
Is this possible ? if true, how ? I would like to do it from both sides: image and VM.
I checked both but I didn't find anything.
Thanks in advance
Mariano _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
participants (6)
-
Adrian Lienhard -
Andreas Raab -
David T. Lewis -
Henrik Johansen -
Henrik Sperre Johansen -
Mariano Martinez Peck