--- a/MemoryUsageView.st Thu Nov 17 15:44:34 1994 +0100
+++ b/MemoryUsageView.st Thu Nov 17 15:47:59 1994 +0100
@@ -42,7 +42,7 @@
version
"
-$Header: /cvs/stx/stx/libtool/MemoryUsageView.st,v 1.3 1994-10-28 03:30:32 claus Exp $
+$Header: /cvs/stx/stx/libtool/MemoryUsageView.st,v 1.4 1994-11-17 14:46:57 claus Exp $
"
!
@@ -90,7 +90,88 @@
(className startsWith:'<') ifFalse:[
(className startsWith:'all') ifFalse:[
class := Smalltalk at:className asSymbol.
- class allInstances inspect
+ self withCursor:(Cursor questionMark) do:[
+ |insts|
+
+ insts := class allInstances.
+ insts size > 500 ifTrue:[
+ (self confirm:'there are ' , insts size printString , ' instances.\\Do you really want to see them all ?' withCRs)
+ ifFalse:[^ self]
+ ].
+ insts inspect
+ ]
+ ]
+ ]
+ ]
+!
+
+inspectOwners
+ |line className class|
+
+ line := list selectionValue.
+ (line notNil and:[line notEmpty]) ifTrue:[
+ className := line asCollectionOfWords first.
+ "
+ special kludge
+ "
+ (className startsWith:'<') ifFalse:[
+ (className startsWith:'all') ifFalse:[
+ class := Smalltalk at:className asSymbol.
+ self withCursor:(Cursor questionMark) do:[
+ |owners dict|
+
+ owners := (ObjectMemory whoReferencesInstancesOf:class).
+ owners isNil ifTrue:[
+ self information:'no owners found - next GC should remove it'.
+ ^ self
+ ].
+ owners := owners asOrderedCollection.
+ owners size > 500 ifTrue:[
+ (self confirm:'there are ' , owners size printString , ' owners.\\Do you really want to see them all ?' withCRs)
+ ifFalse:[^ self]
+ ].
+ dict := IdentityDictionary new.
+ owners do:[:owner |
+ |set names oClass s|
+
+ "
+ skip weakArrays ... (they dont count)
+ "
+ (owner isMemberOf:WeakArray) ifFalse:[
+ set := Set new.
+ names := owner class allInstVarNames.
+ oClass := owner class.
+ 1 to:oClass instSize do:[:i |
+ ((owner instVarAt:i) isMemberOf:class) ifTrue:[
+ set add:(names at:i).
+ ].
+ ].
+ oClass isVariable ifTrue:[
+ oClass isPointers ifTrue:[
+ 1 to:owner basicSize do:[:i |
+ ((owner basicAt:i) isMemberOf:class) ifTrue:[
+ set add:i
+ ]
+ ]
+ ]
+ ].
+ "
+ put a describing string into the dictionary
+ "
+ s := 'references in: '.
+ set do:[:name |
+ name isString ifTrue:[
+ s := s , name , ' '
+ ] ifFalse:[
+ s := s , '[' , name printString , '] '
+ ]
+ ].
+ dict at:owner put:s.
+"/ dict at:owner put:set
+ ]
+ ].
+ dict inspect
+ ]
]
]
]
@@ -114,14 +195,15 @@
updateDisplay
"update the displayed list"
- |classNames counts sumSizes percents avgSizes rawData l line allMemory overAllCount overAllAvgSize|
-
windowGroup withCursor:Cursor wait do:[
+ |classNames counts sumSizes percents avgSizes rawData
+ l line allMemory overAllCount overAllAvgSize|
rawData := info asSortedCollection:sortBlock.
"/ "this avoids getting a sorted collection in the collect: below"
"/ rawData := rawData asArray.
+"/ collect: has been fixed ...
classNames := rawData collect:[:i |
|cls|
@@ -141,11 +223,13 @@
counts := rawData collect:[:i | (i at:2) ].
sumSizes := rawData collect:[:i | (i at:3) ].
allMemory := ObjectMemory bytesUsed.
- percents := sumSizes collect:[:sz | (sz / allMemory * 100 * 10) rounded / 10.0].
+ percents := sumSizes collect:[:sz | (sz asFloat / allMemory * 1000) rounded / 10.0].
avgSizes := (1 to:sumSizes size) collect:[:i | (((sumSizes at:i) / (counts at:i)) * 10) rounded / 10.0].
l := OrderedCollection new.
1 to:classNames size do:[:i |
+ |line|
+
line := (classNames at:i) printStringPaddedTo:30 with:Character space.
line := line , ((counts at:i) printStringLeftPaddedTo:10).
line := line , ((avgSizes at:i) printStringLeftPaddedTo:10).
@@ -173,11 +257,8 @@
updateInfo
"scan all memory and collect the information"
- |myProcess myPriority|
-
windowGroup withCursor:Cursor questionMark do:[
-
- info := IdentityDictionary new:600.
+ |myProcess myPriority|
"find all objects, collect stuff in info"
@@ -188,6 +269,8 @@
myPriority := myProcess priority.
myProcess priority:(Processor userBackgroundPriority).
+ info := IdentityDictionary new:600.
+
[
ObjectMemory allObjectsDo:[:o |
|i class|
@@ -201,12 +284,11 @@
] ifFalse:[
class := o class.
].
- (info includesKey:class) ifFalse:[
- info at:class put:(Array with:class
- with:1
- with:(ObjectMemory sizeOf:o))
- ] ifTrue:[
- i := info at:class.
+ i := info at:class ifAbsent:[].
+ i isNil ifTrue:[
+ i := Array with:class with:1 with:(ObjectMemory sizeOf:o).
+ info at:class put:i.
+ ] ifFalse:[
i at:2 put:((i at:2) + 1).
i at:3 put:((i at:3) + (ObjectMemory sizeOf:o))
]
@@ -238,10 +320,13 @@
helpView := ScrollableView for:SelectionInListView in:self.
helpView origin:(0.0 @ l height) corner:1.0 @ 1.0.
- l origin:(helpView scrollBar width @ 0.0).
+ list := helpView scrolledView.
+
+ l origin:(list originRelativeTo:self) x @ 0.0.
- list := helpView scrolledView.
list font:(self font).
+ l font:(self font).
+
list middleButtonMenu:(PopUpMenu
labels:(
resources array:#(
@@ -250,6 +335,7 @@
'sort by memory usage'
'-'
'inspect instances'
+ 'owners'
'-'
'update'
))
@@ -259,12 +345,15 @@
sortByMemoryUsage
nil
inspectInstances
+ inspectOwners
nil
update
)
receiver:self
for:list).
- "MemoryUsageView start"
+ "
+ MemoryUsageView open
+ "
! !