MemoryUsageView.st
changeset 52 7b48409ae088
parent 49 6fe62433cfa3
child 57 36e13831b62d
equal deleted inserted replaced
51:57c1ccc3d7e0 52:7b48409ae088
    40 "
    40 "
    41 !
    41 !
    42 
    42 
    43 version
    43 version
    44 "
    44 "
    45 $Header: /cvs/stx/stx/libtool/MemoryUsageView.st,v 1.3 1994-10-28 03:30:32 claus Exp $
    45 $Header: /cvs/stx/stx/libtool/MemoryUsageView.st,v 1.4 1994-11-17 14:46:57 claus Exp $
    46 "
    46 "
    47 !
    47 !
    48 
    48 
    49 documentation
    49 documentation
    50 "
    50 "
    88 	 special kludge
    88 	 special kludge
    89 	"
    89 	"
    90 	(className startsWith:'<') ifFalse:[
    90 	(className startsWith:'<') ifFalse:[
    91 	    (className startsWith:'all') ifFalse:[
    91 	    (className startsWith:'all') ifFalse:[
    92 		class := Smalltalk at:className asSymbol.
    92 		class := Smalltalk at:className asSymbol.
    93 		class allInstances inspect
    93 		self withCursor:(Cursor questionMark) do:[
       
    94 		    |insts|
       
    95 
       
    96 		    insts := class allInstances.
       
    97 		    insts size > 500 ifTrue:[
       
    98 			(self confirm:'there are ' , insts size printString , ' instances.\\Do you really want to see them all ?' withCRs)
       
    99 			ifFalse:[^ self]
       
   100 		    ].
       
   101 		    insts inspect
       
   102 		]
       
   103 	    ]
       
   104 	]
       
   105     ]
       
   106 !
       
   107 
       
   108 inspectOwners
       
   109     |line className class|
       
   110 
       
   111     line := list selectionValue.
       
   112     (line notNil and:[line notEmpty]) ifTrue:[
       
   113 	className := line asCollectionOfWords first.
       
   114 	"
       
   115 	 special kludge
       
   116 	"
       
   117 	(className startsWith:'<') ifFalse:[
       
   118 	    (className startsWith:'all') ifFalse:[
       
   119 		class := Smalltalk at:className asSymbol.
       
   120 		self withCursor:(Cursor questionMark) do:[
       
   121 		    |owners dict|
       
   122 
       
   123 		    owners := (ObjectMemory whoReferencesInstancesOf:class).
       
   124 		    owners isNil ifTrue:[
       
   125 			self information:'no owners found - next GC should remove it'.
       
   126 			^ self
       
   127 		    ].
       
   128 		    owners := owners asOrderedCollection.
       
   129 		    owners size > 500 ifTrue:[
       
   130 			(self confirm:'there are ' , owners size printString , ' owners.\\Do you really want to see them all ?' withCRs)
       
   131 			ifFalse:[^ self]
       
   132 		    ].
       
   133 		    dict := IdentityDictionary new.
       
   134 		    owners do:[:owner |
       
   135 			|set names oClass s|
       
   136 
       
   137 			"
       
   138 			 skip weakArrays ... (they dont count)
       
   139 			"
       
   140 			(owner isMemberOf:WeakArray) ifFalse:[
       
   141 			    set := Set new.
       
   142 			    names := owner class allInstVarNames.
       
   143 			    oClass := owner class.
       
   144 			    1 to:oClass instSize do:[:i |
       
   145 				((owner instVarAt:i) isMemberOf:class) ifTrue:[
       
   146 				    set add:(names at:i).
       
   147 				].
       
   148 			    ].
       
   149 			    oClass isVariable ifTrue:[
       
   150 				oClass isPointers ifTrue:[
       
   151 				    1 to:owner basicSize do:[:i |
       
   152 					((owner basicAt:i) isMemberOf:class) ifTrue:[
       
   153 					    set add:i
       
   154 					]
       
   155 				    ]
       
   156 				]
       
   157 			    ].
       
   158 			    "
       
   159 			     put a describing string into the dictionary
       
   160 			    "
       
   161 			    s := 'references in: '.
       
   162 			    set do:[:name | 
       
   163 					name isString ifTrue:[
       
   164 					    s := s , name , ' '
       
   165 					] ifFalse:[
       
   166 					    s := s , '[' , name printString , '] '
       
   167 					]
       
   168 				   ].
       
   169 			    dict at:owner put:s.
       
   170 "/                            dict at:owner put:set
       
   171 			]
       
   172 		    ].
       
   173 		    dict inspect
       
   174 		]
    94 	    ]
   175 	    ]
    95 	]
   176 	]
    96     ]
   177     ]
    97 !
   178 !
    98 
   179 
   112 !MemoryUsageView methodsFor:'private'!
   193 !MemoryUsageView methodsFor:'private'!
   113 
   194 
   114 updateDisplay
   195 updateDisplay
   115     "update the displayed list"
   196     "update the displayed list"
   116 
   197 
   117     |classNames counts sumSizes percents avgSizes rawData l line allMemory overAllCount overAllAvgSize|
       
   118 
       
   119     windowGroup withCursor:Cursor wait do:[
   198     windowGroup withCursor:Cursor wait do:[
       
   199 	|classNames counts sumSizes percents avgSizes rawData 
       
   200 	 l line allMemory overAllCount overAllAvgSize|
   120 
   201 
   121 	rawData := info asSortedCollection:sortBlock.
   202 	rawData := info asSortedCollection:sortBlock.
   122 
   203 
   123 "/        "this avoids getting a sorted collection in the collect: below"
   204 "/        "this avoids getting a sorted collection in the collect: below"
   124 "/        rawData := rawData asArray.
   205 "/        rawData := rawData asArray.
       
   206 "/ collect: has been fixed ...
   125 
   207 
   126 	classNames := rawData collect:[:i | 
   208 	classNames := rawData collect:[:i | 
   127 	    |cls|
   209 	    |cls|
   128 
   210 
   129 	    cls := i at:1.
   211 	    cls := i at:1.
   139 	].
   221 	].
   140 
   222 
   141 	counts := rawData collect:[:i | (i at:2) ].
   223 	counts := rawData collect:[:i | (i at:2) ].
   142 	sumSizes := rawData collect:[:i | (i at:3) ].
   224 	sumSizes := rawData collect:[:i | (i at:3) ].
   143 	allMemory := ObjectMemory bytesUsed.
   225 	allMemory := ObjectMemory bytesUsed.
   144 	percents := sumSizes collect:[:sz | (sz / allMemory * 100 * 10) rounded / 10.0].
   226 	percents := sumSizes collect:[:sz | (sz asFloat / allMemory * 1000) rounded / 10.0].
   145 	avgSizes := (1 to:sumSizes size) collect:[:i | (((sumSizes at:i) / (counts at:i)) * 10) rounded / 10.0].
   227 	avgSizes := (1 to:sumSizes size) collect:[:i | (((sumSizes at:i) / (counts at:i)) * 10) rounded / 10.0].
   146 
   228 
   147 	l := OrderedCollection new.
   229 	l := OrderedCollection new.
   148 	1 to:classNames size do:[:i |
   230 	1 to:classNames size do:[:i |
       
   231 	    |line|
       
   232 
   149 	    line := (classNames at:i) printStringPaddedTo:30 with:Character space.
   233 	    line := (classNames at:i) printStringPaddedTo:30 with:Character space.
   150 	    line := line , ((counts at:i) printStringLeftPaddedTo:10).
   234 	    line := line , ((counts at:i) printStringLeftPaddedTo:10).
   151 	    line := line , ((avgSizes at:i) printStringLeftPaddedTo:10).
   235 	    line := line , ((avgSizes at:i) printStringLeftPaddedTo:10).
   152 	    line := line , ((sumSizes at:i) printStringLeftPaddedTo:10).
   236 	    line := line , ((sumSizes at:i) printStringLeftPaddedTo:10).
   153 	    line := line , ((percents at:i) printStringLeftPaddedTo:7).
   237 	    line := line , ((percents at:i) printStringLeftPaddedTo:7).
   171 !
   255 !
   172 
   256 
   173 updateInfo
   257 updateInfo
   174     "scan all memory and collect the information"
   258     "scan all memory and collect the information"
   175 
   259 
   176     |myProcess myPriority|
       
   177 
       
   178     windowGroup withCursor:Cursor questionMark do:[
   260     windowGroup withCursor:Cursor questionMark do:[
   179 
   261 	|myProcess myPriority|
   180 	info := IdentityDictionary new:600.
       
   181 
   262 
   182 	"find all objects, collect stuff in info"
   263 	"find all objects, collect stuff in info"
   183 
   264 
   184 	"
   265 	"
   185 	 this is a time consuming operation; therefore lower my priority ...
   266 	 this is a time consuming operation; therefore lower my priority ...
   186 	"
   267 	"
   187 	myProcess := Processor activeProcess.
   268 	myProcess := Processor activeProcess.
   188 	myPriority := myProcess priority.
   269 	myPriority := myProcess priority.
   189 	myProcess priority:(Processor userBackgroundPriority).
   270 	myProcess priority:(Processor userBackgroundPriority).
       
   271 
       
   272 	info := IdentityDictionary new:600.
   190 
   273 
   191 	[
   274 	[
   192 	    ObjectMemory allObjectsDo:[:o |
   275 	    ObjectMemory allObjectsDo:[:o |
   193 		|i class|
   276 		|i class|
   194 
   277 
   199 			class := Class
   282 			class := Class
   200 		    ]
   283 		    ]
   201 		] ifFalse:[
   284 		] ifFalse:[
   202 		    class := o class.
   285 		    class := o class.
   203 		].
   286 		].
   204 		(info includesKey:class) ifFalse:[
   287 		i := info at:class ifAbsent:[].
   205 		    info at:class put:(Array with:class 
   288 		i isNil ifTrue:[
   206 					     with:1 
   289 		    i := Array with:class with:1 with:(ObjectMemory sizeOf:o).
   207 					     with:(ObjectMemory sizeOf:o))
   290 		    info at:class put:i.
   208 		] ifTrue:[
   291 		] ifFalse:[
   209 		    i := info at:class.
       
   210 		    i at:2 put:((i at:2) + 1).
   292 		    i at:2 put:((i at:2) + 1).
   211 		    i at:3 put:((i at:3) + (ObjectMemory sizeOf:o))
   293 		    i at:3 put:((i at:3) + (ObjectMemory sizeOf:o))
   212 		]
   294 		]
   213 	    ].
   295 	    ].
   214 	] valueNowOrOnUnwindDo:[
   296 	] valueNowOrOnUnwindDo:[
   236     self extent:((font widthOf:headLine) + (device horizontalPixelPerMillimeter * 15) rounded) @ self height.
   318     self extent:((font widthOf:headLine) + (device horizontalPixelPerMillimeter * 15) rounded) @ self height.
   237 
   319 
   238     helpView := ScrollableView for:SelectionInListView in:self.
   320     helpView := ScrollableView for:SelectionInListView in:self.
   239     helpView origin:(0.0 @ l height) corner:1.0 @ 1.0.
   321     helpView origin:(0.0 @ l height) corner:1.0 @ 1.0.
   240 
   322 
   241     l origin:(helpView scrollBar width @ 0.0).
       
   242 
       
   243     list := helpView scrolledView.
   323     list := helpView scrolledView.
       
   324 
       
   325     l origin:(list originRelativeTo:self) x @ 0.0.
       
   326 
   244     list font:(self font).
   327     list font:(self font).
       
   328     l font:(self font).
       
   329 
   245     list middleButtonMenu:(PopUpMenu
   330     list middleButtonMenu:(PopUpMenu
   246 				labels:(
   331 				labels:(
   247 					resources array:#(
   332 					resources array:#(
   248 					    'sort by class'
   333 					    'sort by class'
   249 					    'sort by inst count'
   334 					    'sort by inst count'
   250 					    'sort by memory usage'
   335 					    'sort by memory usage'
   251 					    '-'
   336 					    '-'
   252 					    'inspect instances'
   337 					    'inspect instances'
       
   338 					    'owners'
   253 					    '-'
   339 					    '-'
   254 					    'update'
   340 					    'update'
   255 					))
   341 					))
   256 
   342 
   257 			     selectors:#(sortByClass
   343 			     selectors:#(sortByClass
   258 					 sortByInstCount
   344 					 sortByInstCount
   259 					 sortByMemoryUsage
   345 					 sortByMemoryUsage
   260 					 nil
   346 					 nil
   261 					 inspectInstances
   347 					 inspectInstances
       
   348 					 inspectOwners
   262 					 nil
   349 					 nil
   263 					 update
   350 					 update
   264 					)
   351 					)
   265 				receiver:self
   352 				receiver:self
   266 				     for:list).
   353 				     for:list).
   267 
   354 
   268     "MemoryUsageView start"
   355     "
   269 ! !
   356      MemoryUsageView open
   270 
   357     "
       
   358 ! !
       
   359