|
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 |