MemoryUsageView.st
changeset 45 950b84ba89e6
parent 19 4cde336c0794
child 49 6fe62433cfa3
equal deleted inserted replaced
44:5f101bc4a0ca 45:950b84ba89e6
       
     1 "
       
     2  COPYRIGHT (c) 1992 by Claus Gittinger
       
     3 	      All Rights Reserved
       
     4 
       
     5  This software is furnished under a license and may be used
       
     6  only in accordance with the terms of that license and with the
       
     7  inclusion of the above copyright notice.   This software may not
       
     8  be provided or otherwise made available to, or used by, any
       
     9  other person.  No title to or ownership of the software is
       
    10  hereby transferred.
       
    11 "
       
    12 
       
    13 'From Smalltalk/X, Version:2.10.3 on 30-sep-1994 at 11:13:14'!
       
    14 
     1 StandardSystemView subclass:#MemoryUsageView
    15 StandardSystemView subclass:#MemoryUsageView
     2          instanceVariableNames:'info list sortBlock'
    16 	 instanceVariableNames:'info list sortBlock'
     3          classVariableNames:''
    17 	 classVariableNames:''
     4          poolDictionaries:''
    18 	 poolDictionaries:''
     5          category:'Interface-Debugger'
    19 	 category:'Interface-Tools'
     6 !
    20 !
       
    21 
       
    22 MemoryUsageView comment:'
       
    23  COPYRIGHT (c) 1992 by Claus Gittinger
       
    24 	      All Rights Reserved
       
    25 '!
       
    26 
       
    27 !MemoryUsageView class methodsFor:'documentation'!
       
    28 
       
    29 copyright
       
    30 "
       
    31  COPYRIGHT (c) 1992 by Claus Gittinger
       
    32 	      All Rights Reserved
       
    33 
       
    34  This software is furnished under a license and may be used
       
    35  only in accordance with the terms of that license and with the
       
    36  inclusion of the above copyright notice.   This software may not
       
    37  be provided or otherwise made available to, or used by, any
       
    38  other person.  No title to or ownership of the software is
       
    39  hereby transferred.
       
    40 "
       
    41 !
       
    42 
       
    43 version
       
    44 "
       
    45 $Header: /cvs/stx/stx/libtool/MemoryUsageView.st,v 1.2 1994-10-10 03:15:56 claus Exp $
       
    46 "
       
    47 !
       
    48 
       
    49 documentation
       
    50 "
       
    51     this view shows an overview over the memory usage of the system.
       
    52     usage:
       
    53 	MemoryUsageView new open
       
    54 
       
    55     Since scanning all memory takes some time, this is not done
       
    56     automatically, but upon request. See the middlebuttonmenu-'update'
       
    57     function.
       
    58 "
       
    59 ! !
       
    60 
       
    61 !MemoryUsageView methodsFor:'menu actions'!
       
    62 
       
    63 sortByClass
       
    64     self label:'Memory usage; by class'.
       
    65     sortBlock := [:a :b | (a at:1) name < (b at:1) name].
       
    66     self updateDisplay
       
    67 !
       
    68 
       
    69 sortByInstCount
       
    70     self label:'Memory usage; by instance count'.
       
    71     sortBlock := [:a :b | (a at:2) > (b at:2) ].
       
    72     self updateDisplay
       
    73 !
       
    74 
       
    75 sortByMemoryUsage
       
    76     self label:'Memory usage; by memory usage'.
       
    77     sortBlock := [:a :b | (a at:3) > (b at:3)].
       
    78     self updateDisplay
       
    79 !
       
    80 
       
    81 inspectInstances
       
    82     |line className class|
       
    83 
       
    84     line := list selectionValue.
       
    85     (line notNil and:[line notEmpty]) ifTrue:[
       
    86 	className := line asCollectionOfWords first.
       
    87 	"
       
    88 	 special kludge
       
    89 	"
       
    90 	(className startsWith:'<') ifFalse:[
       
    91 	    (className startsWith:'all') ifFalse:[
       
    92 		class := Smalltalk at:className asSymbol.
       
    93 		class allInstances inspect
       
    94 	    ]
       
    95 	]
       
    96     ]
       
    97 !
       
    98 
       
    99 update
       
   100     self updateInfo.
       
   101     self updateDisplay
       
   102 ! !
     7 
   103 
     8 !MemoryUsageView methodsFor:'realization'!
   104 !MemoryUsageView methodsFor:'realization'!
     9 
   105 
    10 realize
   106 realize
    11     super realize.
   107     super realize.
    12     self updateInfo.
   108     self updateInfo.
    13     self sortByClass.
   109     self sortByClass.
    14 ! !
   110 ! !
    15 
   111 
    16 !MemoryUsageView methodsFor:'initialization'!
       
    17 
       
    18 initialize
       
    19     |l helpView headLine|
       
    20 
       
    21     super initialize.
       
    22     self label:'Memory usage'.
       
    23 
       
    24     headLine := 'class                           # of insts  avg sz     bytes   %mem'.
       
    25 
       
    26     l := Label in:self.
       
    27     l origin:(0.0 @ 0.0) corner:(1.0 @ l height).
       
    28     l borderWidth:0.
       
    29     l label:headLine.
       
    30     l adjust:#left.
       
    31 
       
    32     self extent:((font widthOf:headLine) + (device horizontalPixelPerMillimeter * 15) rounded) @ self height.
       
    33 
       
    34     helpView := ScrollableView for:ListView in:self.
       
    35     helpView origin:(0.0 @ l height)
       
    36              extent:[width @ (height - l height - l margin)].
       
    37 
       
    38     l origin:(helpView scrollBar width @ 0.0).
       
    39 
       
    40     list := helpView scrolledView.
       
    41     list origin:(0.0 @ 0.0) extent:(1.0 @ 1.0).
       
    42 
       
    43     list middleButtonMenu:(PopUpMenu
       
    44                                 labels:#(
       
    45                                          'by class'
       
    46                                          'by inst count'
       
    47                                          'by memory usage'
       
    48                                          '-'
       
    49                                          'update'
       
    50                                         )
       
    51 
       
    52                              selectors:#(sortByClass
       
    53                                          sortByInstCount
       
    54                                          sortByMemoryUsage
       
    55                                          nil
       
    56                                          update
       
    57                                         )
       
    58                                 receiver:self
       
    59                                      for:list).
       
    60 
       
    61     "MemoryUsageView start"
       
    62 ! !
       
    63 
       
    64 !MemoryUsageView methodsFor:'menu actions'!
       
    65 
       
    66 sortByClass
       
    67     self label:'Memory usage; by class'.
       
    68     sortBlock := [:a :b | (a at:1) name < (b at:1) name].
       
    69     self updateDisplay
       
    70 !
       
    71 
       
    72 sortByInstCount
       
    73     self label:'Memory usage; by instance count'.
       
    74     sortBlock := [:a :b | (a at:2) > (b at:2) ].
       
    75     self updateDisplay
       
    76 !
       
    77 
       
    78 sortByMemoryUsage
       
    79     self label:'Memory usage; by memory usage'.
       
    80     sortBlock := [:a :b | (a at:3) > (b at:3)].
       
    81     self updateDisplay
       
    82 !
       
    83 
       
    84 update
       
    85     self updateInfo.
       
    86     self updateDisplay
       
    87 ! !
       
    88 
       
    89 !MemoryUsageView methodsFor:'private'!
   112 !MemoryUsageView methodsFor:'private'!
    90 
   113 
    91 updateInfo
       
    92     self cursor:Cursor wait.
       
    93     list cursor:Cursor wait.
       
    94 
       
    95     info := IdentityDictionary new:600.
       
    96 
       
    97     "find all objects, collect stuff in info"
       
    98 
       
    99     ObjectMemory allObjectsDo:[:o |
       
   100         |i class|
       
   101 
       
   102         o isBehavior ifTrue:[
       
   103             o isMeta ifTrue:[
       
   104                 class := Metaclass
       
   105             ] ifFalse:[
       
   106                 class := Class
       
   107             ]
       
   108         ] ifFalse:[
       
   109             class := o class.
       
   110         ].
       
   111         (info includesKey:class) ifFalse:[
       
   112             info at:class put:(Array with:class 
       
   113                                      with:1 
       
   114                                      with:(ObjectMemory sizeOf:o))
       
   115         ] ifTrue:[
       
   116             i := info at:class.
       
   117             i at:2 put:((i at:2) + 1).
       
   118             i at:3 put:((i at:3) + (ObjectMemory sizeOf:o))
       
   119         ]
       
   120     ].
       
   121 
       
   122     self cursor:Cursor normal.
       
   123     list cursor:Cursor normal.
       
   124 ! 
       
   125 
       
   126 updateDisplay
   114 updateDisplay
       
   115     "update the displayed list"
       
   116 
   127     |classNames counts sumSizes percents avgSizes rawData l line allMemory overAllCount overAllAvgSize|
   117     |classNames counts sumSizes percents avgSizes rawData l line allMemory overAllCount overAllAvgSize|
   128 
       
   129     self cursor:Cursor wait.
       
   130     list cursor:Cursor wait.
       
   131 
   118 
   132     rawData := info asSortedCollection:sortBlock.
   119     rawData := info asSortedCollection:sortBlock.
   133 
   120 
   134     "this avoids getting a sorted collection in the collect: below"
   121     "this avoids getting a sorted collection in the collect: below"
   135     rawData := rawData asArray.
   122     rawData := rawData asArray.
   136 
   123 
   137     classNames := rawData collect:[:i | 
   124     classNames := rawData collect:[:i | 
   138         |cls|
   125 	|cls|
   139 
   126 
   140         cls := i at:1.
   127 	cls := i at:1.
   141         cls == Class ifTrue:[
   128 	cls == Class ifTrue:[
   142             '<all classes>'
   129 	    '<all classes>'
   143         ] ifFalse:[
   130 	] ifFalse:[
   144             cls == Metaclass ifTrue:[
   131 	    cls == Metaclass ifTrue:[
   145                 '<all metaclasses>'
   132 		'<all metaclasses>'
   146             ] ifFalse:[
   133 	    ] ifFalse:[
   147                 cls name
   134 		cls name
   148             ] 
   135 	    ] 
   149         ] 
   136 	] 
   150     ].
   137     ].
   151 
   138 
   152     counts := rawData collect:[:i | (i at:2) ].
   139     counts := rawData collect:[:i | (i at:2) ].
   153     sumSizes := rawData collect:[:i | (i at:3) ].
   140     sumSizes := rawData collect:[:i | (i at:3) ].
   154     allMemory := ObjectMemory bytesUsed.
   141     allMemory := ObjectMemory bytesUsed.
   155     percents := sumSizes collect:[:sz | (sz / allMemory * 100 * 10) rounded / 10.0].
   142     percents := sumSizes collect:[:sz | (sz / allMemory * 100 * 10) rounded / 10.0].
   156     avgSizes := (1 to:sumSizes size) collect:[:i | (((sumSizes at:i) / (counts at:i)) * 10) rounded / 10.0].
   143     avgSizes := (1 to:sumSizes size) collect:[:i | (((sumSizes at:i) / (counts at:i)) * 10) rounded / 10.0].
   157 
   144 
   158     l := OrderedCollection new.
   145     l := OrderedCollection new.
   159     1 to:classNames size do:[:i |
   146     1 to:classNames size do:[:i |
   160         line := (classNames at:i) printStringPaddedTo:30 with:Character space.
   147 	line := (classNames at:i) printStringPaddedTo:30 with:Character space.
   161         line := line , ((counts at:i) printStringLeftPaddedTo:10).
   148 	line := line , ((counts at:i) printStringLeftPaddedTo:10).
   162         line := line , ((avgSizes at:i) printStringLeftPaddedTo:10).
   149 	line := line , ((avgSizes at:i) printStringLeftPaddedTo:10).
   163         line := line , ((sumSizes at:i) printStringLeftPaddedTo:10).
   150 	line := line , ((sumSizes at:i) printStringLeftPaddedTo:10).
   164         line := line , ((percents at:i) printStringLeftPaddedTo:7).
   151 	line := line , ((percents at:i) printStringLeftPaddedTo:7).
   165         l add:line
   152 	l add:line
   166     ].
   153     ].
   167 
   154 
   168     "add summary line"
   155     "add summary line"
   169     overAllCount := counts inject:0 into:[:sum :this | sum + this].
   156     overAllCount := counts inject:0 into:[:sum :this | sum + this].
   170     overAllAvgSize := ((allMemory / overAllCount) * 10) rounded / 10.0.
   157     overAllAvgSize := ((allMemory / overAllCount) * 10) rounded / 10.0.
   176     line := line , (allMemory printStringLeftPaddedTo:10).
   163     line := line , (allMemory printStringLeftPaddedTo:10).
   177     line := line , (100.0 printStringLeftPaddedTo:7).
   164     line := line , (100.0 printStringLeftPaddedTo:7).
   178     l add:line.
   165     l add:line.
   179 
   166 
   180     list list:l.
   167     list list:l.
   181 
   168 !
   182     self cursor:Cursor normal.
   169 
   183     list cursor:Cursor normal.
   170 updateInfo
   184 ! !
   171     "scan all memory and collect the information"
       
   172 
       
   173     |myProcess myPriority|
       
   174 
       
   175     windowGroup withCursor:Cursor wait do:[
       
   176 
       
   177 	info := IdentityDictionary new:600.
       
   178 
       
   179 	"find all objects, collect stuff in info"
       
   180 
       
   181 	"
       
   182 	 this is a time consuming operation; therefore lower my priority ...
       
   183 	"
       
   184 	myProcess := Processor activeProcess.
       
   185 	myPriority := myProcess priority.
       
   186 	myProcess priority:(Processor userBackgroundPriority).
       
   187 
       
   188 	[
       
   189 	    ObjectMemory allObjectsDo:[:o |
       
   190 		|i class|
       
   191 
       
   192 		o isBehavior ifTrue:[
       
   193 		    o isMeta ifTrue:[
       
   194 			class := Metaclass
       
   195 		    ] ifFalse:[
       
   196 			class := Class
       
   197 		    ]
       
   198 		] ifFalse:[
       
   199 		    class := o class.
       
   200 		].
       
   201 		(info includesKey:class) ifFalse:[
       
   202 		    info at:class put:(Array with:class 
       
   203 					     with:1 
       
   204 					     with:(ObjectMemory sizeOf:o))
       
   205 		] ifTrue:[
       
   206 		    i := info at:class.
       
   207 		    i at:2 put:((i at:2) + 1).
       
   208 		    i at:3 put:((i at:3) + (ObjectMemory sizeOf:o))
       
   209 		]
       
   210 	    ].
       
   211 	] valueNowOrOnUnwindDo:[
       
   212 	    myProcess priority:myPriority.
       
   213 	].
       
   214     ]
       
   215 ! !
       
   216 
       
   217 !MemoryUsageView methodsFor:'initialization'!
       
   218 
       
   219 initialize
       
   220     |l helpView headLine|
       
   221 
       
   222     super initialize.
       
   223     self label:'Memory usage'.
       
   224 
       
   225     headLine := ' class                           # of insts  avg sz     bytes   %mem '.
       
   226 
       
   227     l := Label in:self.
       
   228     l origin:(0.0 @ 0.0) corner:(1.0 @ l height).
       
   229     l borderWidth:0.
       
   230     l label:headLine.
       
   231     l adjust:#left.
       
   232 
       
   233     self extent:((font widthOf:headLine) + (device horizontalPixelPerMillimeter * 15) rounded) @ self height.
       
   234 
       
   235     helpView := ScrollableView for:SelectionInListView in:self.
       
   236     helpView origin:(0.0 @ l height) corner:1.0 @ 1.0.
       
   237 
       
   238     l origin:(helpView scrollBar width @ 0.0).
       
   239 
       
   240     list := helpView scrolledView.
       
   241     list font:(self font).
       
   242     list middleButtonMenu:(PopUpMenu
       
   243 				labels:(
       
   244 					resources array:#(
       
   245 					    'sort by class'
       
   246 					    'sort by inst count'
       
   247 					    'sort by memory usage'
       
   248 					    '-'
       
   249 					    'inspect instances'
       
   250 					    '-'
       
   251 					    'update'
       
   252 					))
       
   253 
       
   254 			     selectors:#(sortByClass
       
   255 					 sortByInstCount
       
   256 					 sortByMemoryUsage
       
   257 					 nil
       
   258 					 inspectInstances
       
   259 					 nil
       
   260 					 update
       
   261 					)
       
   262 				receiver:self
       
   263 				     for:list).
       
   264 
       
   265     "MemoryUsageView start"
       
   266 ! !
       
   267