Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: runtime/observatory/lib/src/elements/memory/graph.dart

Issue 2999933002: Revert "Add current rss and embedder name to Observatory" (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// This Element is part of MemoryDashboardElement. 5 /// This Element is part of MemoryDashboardElement.
6 /// 6 ///
7 /// The Element periodically interrogates the VM to log the memory usage of each 7 /// The Element periodically interrogates the VM to log the memory usage of each
8 /// Isolate and of the Native Memory. 8 /// Isolate and of the Native Memory.
9 /// 9 ///
10 /// For each isolate it is shown the Used and Free heap (new and old are merged 10 /// For each isolate it is shown the Used and Free heap (new and old are merged
(...skipping 23 matching lines...) Expand all
34 34
35 RenderingScheduler<MemoryGraphElement> _r; 35 RenderingScheduler<MemoryGraphElement> _r;
36 36
37 final StreamController<IsolateSelectedEvent> _onIsolateSelected = 37 final StreamController<IsolateSelectedEvent> _onIsolateSelected =
38 new StreamController<IsolateSelectedEvent>(); 38 new StreamController<IsolateSelectedEvent>();
39 39
40 Stream<RenderedEvent<MemoryGraphElement>> get onRendered => _r.onRendered; 40 Stream<RenderedEvent<MemoryGraphElement>> get onRendered => _r.onRendered;
41 Stream<IsolateSelectedEvent> get onIsolateSelected => 41 Stream<IsolateSelectedEvent> get onIsolateSelected =>
42 _onIsolateSelected.stream; 42 _onIsolateSelected.stream;
43 43
44 M.VMRef _vm; 44 M.VM _vm;
45 M.VMRepository _vms;
46 M.IsolateRepository _isolates; 45 M.IsolateRepository _isolates;
47 M.EventRepository _events; 46 M.EventRepository _events;
48 StreamSubscription _onGCSubscription; 47 StreamSubscription _onGCSubscription;
49 StreamSubscription _onResizeSubscription; 48 StreamSubscription _onResizeSubscription;
50 StreamSubscription _onConnectionClosedSubscription; 49 StreamSubscription _onConnectionClosedSubscription;
51 Timer _onTimer; 50 Timer _onTimer;
52 51
53 M.VMRef get vm => _vm; 52 M.VM get vm => _vm;
54 53
55 factory MemoryGraphElement(M.VMRef vm, M.VMRepository vms, 54 factory MemoryGraphElement(
56 M.IsolateRepository isolates, M.EventRepository events, 55 M.VM vm, M.IsolateRepository isolates, M.EventRepository events,
57 {RenderingQueue queue}) { 56 {RenderingQueue queue}) {
58 assert(vm != null); 57 assert(vm != null);
59 assert(vms != null);
60 assert(isolates != null); 58 assert(isolates != null);
61 assert(events != null); 59 assert(events != null);
62 MemoryGraphElement e = document.createElement(tag.name); 60 MemoryGraphElement e = document.createElement(tag.name);
63 e._r = new RenderingScheduler(e, queue: queue); 61 e._r = new RenderingScheduler(e, queue: queue);
64 e._vm = vm; 62 e._vm = vm;
65 e._vms = vms;
66 e._isolates = isolates; 63 e._isolates = isolates;
67 e._events = events; 64 e._events = events;
68 return e; 65 return e;
69 } 66 }
70 67
71 MemoryGraphElement.created() : super.created() { 68 MemoryGraphElement.created() : super.created() {
72 final now = new DateTime.now(); 69 final now = new DateTime.now();
73 var sample = now.subtract(_window); 70 var sample = now.subtract(_window);
74 while (sample.isBefore(now)) { 71 while (sample.isBefore(now)) {
75 _ts.add(sample); 72 _ts.add(sample);
76 _vmSamples.add(<int>[0, 0]); 73 _vmSamples.add(0);
77 _isolateUsedSamples.add([]); 74 _isolateUsedSamples.add([]);
78 _isolateFreeSamples.add([]); 75 _isolateFreeSamples.add([]);
79 sample = sample.add(_period); 76 sample = sample.add(_period);
80 } 77 }
81 _ts.add(now); 78 _ts.add(now);
82 _vmSamples.add(<int>[0, 0]); 79 _vmSamples.add(0);
83 _isolateUsedSamples.add([]); 80 _isolateUsedSamples.add([]);
84 _isolateFreeSamples.add([]); 81 _isolateFreeSamples.add([]);
85 } 82 }
86 83
87 static const Duration _period = const Duration(seconds: 2); 84 static const Duration _period = const Duration(seconds: 2);
88 static const Duration _window = const Duration(minutes: 2); 85 static const Duration _window = const Duration(minutes: 2);
89 86
90 @override 87 @override
91 attached() { 88 attached() {
92 super.attached(); 89 super.attached();
(...skipping 12 matching lines...) Expand all
105 super.detached(); 102 super.detached();
106 _r.disable(notify: true); 103 _r.disable(notify: true);
107 children = []; 104 children = [];
108 _onGCSubscription.cancel(); 105 _onGCSubscription.cancel();
109 _onConnectionClosedSubscription.cancel(); 106 _onConnectionClosedSubscription.cancel();
110 _onResizeSubscription.cancel(); 107 _onResizeSubscription.cancel();
111 _onTimer.cancel(); 108 _onTimer.cancel();
112 } 109 }
113 110
114 final List<DateTime> _ts = <DateTime>[]; 111 final List<DateTime> _ts = <DateTime>[];
115 final List<List<int>> _vmSamples = <List<int>>[]; 112 final List<int> _vmSamples = <int>[];
116 final List<M.IsolateRef> _seenIsolates = <M.IsolateRef>[]; 113 final List<M.IsolateRef> _seenIsolates = <M.IsolateRef>[];
117 final List<List<int>> _isolateUsedSamples = <List<int>>[]; 114 final List<List<int>> _isolateUsedSamples = <List<int>>[];
118 final List<List<int>> _isolateFreeSamples = <List<int>>[]; 115 final List<List<int>> _isolateFreeSamples = <List<int>>[];
119 final Map<String, int> _isolateIndex = <String, int>{}; 116 final Map<String, int> _isolateIndex = <String, int>{};
120 final Map<String, String> _isolateName = <String, String>{}; 117 final Map<String, String> _isolateName = <String, String>{};
121 118
122 var _selected; 119 var _selected;
123 var _previewed; 120 var _previewed;
124 var _hovered; 121 var _hovered;
125 122
126 void render() { 123 void render() {
127 if (_previewed != null || _hovered != null) return; 124 if (_previewed != null || _hovered != null) return;
128 125
129 // cache data of hoverboards
130 final ts = new List<DateTime>.from(_ts);
131 final vmSamples = new List<List<int>>.from(_vmSamples);
132 final isolateFreeSamples = new List<List<int>>.from(_isolateFreeSamples);
133 final isolateUsedSamples = new List<List<int>>.from(_isolateUsedSamples);
134
135 final now = _ts.last; 126 final now = _ts.last;
136 final nativeComponents = 1; 127 final nativeComponents = 1;
137 final legend = new DivElement(); 128 final legend = new DivElement();
138 final host = new DivElement(); 129 final host = new DivElement();
139 final theme = new MemoryChartTheme(1); 130 final theme = new MemoryChartTheme(1);
140 children = [theme.style, legend, host]; 131 children = [theme.style, legend, host];
141 final rect = host.getBoundingClientRect(); 132 final rect = host.getBoundingClientRect();
142 133
143 final series = 134 final series =
144 new List<int>.generate(_isolateIndex.length * 2 + 1, (i) => i + 1); 135 new List<int>.generate(_isolateIndex.length * 2 + 1, (i) => i + 1);
145 // The stacked line chart sorts from top to bottom 136 // The stacked line chart sorts from top to bottom
146 final columns = [ 137 final columns = [
147 new ChartColumnSpec( 138 new ChartColumnSpec(
148 formatter: _formatTimeAxis, type: ChartColumnSpec.TYPE_NUMBER), 139 formatter: _formatTimeAxis, type: ChartColumnSpec.TYPE_NUMBER),
149 new ChartColumnSpec(label: 'Native', formatter: Utils.formatSize) 140 new ChartColumnSpec(label: 'Native', formatter: Utils.formatSize)
150 ]..addAll(_isolateName.keys.expand((id) => [ 141 ]..addAll(_isolateName.keys.expand((id) => [
151 new ChartColumnSpec(formatter: Utils.formatSize), 142 new ChartColumnSpec(formatter: Utils.formatSize),
152 new ChartColumnSpec(label: _label(id), formatter: Utils.formatSize) 143 new ChartColumnSpec(label: _label(id), formatter: Utils.formatSize)
153 ])); 144 ]));
154 // The stacked line chart sorts from top to bottom 145 // The stacked line chart sorts from top to bottom
155 final rows = new List.generate(_ts.length, (sampleIndex) { 146 final rows = new List.generate(_ts.length, (sampleIndex) {
156 final free = isolateFreeSamples[sampleIndex]; 147 final free = _isolateFreeSamples[sampleIndex];
157 final used = isolateUsedSamples[sampleIndex]; 148 final used = _isolateUsedSamples[sampleIndex];
158 final isolates = _isolateIndex.keys.expand((key) {
159 final isolateIndex = _isolateIndex[key];
160 return <int>[free[isolateIndex], used[isolateIndex]];
161 });
162 return [ 149 return [
163 ts[sampleIndex].difference(now).inMicroseconds, 150 _ts[sampleIndex].difference(now).inMicroseconds,
164 vmSamples[sampleIndex][1] ?? 1000000 151 _vmSamples[sampleIndex]
165 ]..addAll(isolates); 152 ]..addAll(_isolateIndex.keys.expand((key) {
153 final isolateIndex = _isolateIndex[key];
154 return [free[isolateIndex], used[isolateIndex]];
155 }));
166 }); 156 });
167 157
168 final scale = new LinearScale()..domain = [(-_window).inMicroseconds, 0]; 158 final scale = new LinearScale()..domain = [(-_window).inMicroseconds, 0];
169 final axisConfig = new ChartAxisConfig()..scale = scale; 159 final axisConfig = new ChartAxisConfig()..scale = scale;
170 final sMemory = 160 final sMemory =
171 new ChartSeries('Memory', series, new StackedLineChartRenderer()); 161 new ChartSeries('Memory', series, new StackedLineChartRenderer());
172 final config = new ChartConfig([sMemory], [0]) 162 final config = new ChartConfig([sMemory], [0])
173 ..legend = new ChartLegend(legend) 163 ..legend = new ChartLegend(legend)
174 ..registerDimensionAxis(0, axisConfig); 164 ..registerDimensionAxis(0, axisConfig);
175 config.minimumSize = new Rect(rect.width, rect.height); 165 config.minimumSize = new Rect(rect.width, rect.height);
176 final data = new ChartData(columns, rows); 166 final data = new ChartData(columns, rows);
177 final state = new ChartState(isMultiSelect: true) 167 final state = new ChartState(isMultiSelect: true)
178 ..changes.listen(_handleEvent); 168 ..changes.listen(_handleEvent);
179 final area = new CartesianArea(host, data, config, state: state) 169 final area = new CartesianArea(host, data, config, state: state)
180 ..theme = theme; 170 ..theme = theme;
181 area.addChartBehavior(new Hovercard(builder: (int column, int row) { 171 area.addChartBehavior(new Hovercard(builder: (int column, int row) {
172 final data = rows[row];
182 if (column == 1) { 173 if (column == 1) {
183 final data = vmSamples[row]; 174 return _formatNativeOvercard(data[1]);
184 return _formatNativeOvercard(data[0], data[1]);
185 } 175 }
186 final isolate = _seenIsolates[column - 2]; 176 final isolate = _seenIsolates[column - 2];
187 final index = _isolateIndex[isolate.id]; 177 final index = _isolateIndex[isolate.id] * 2 + 2;
188 final free = isolateFreeSamples[row][index]; 178 return _formatIsolateOvercard(isolate.name, data[index], data[index + 1]);
189 final used = isolateUsedSamples[row][index];
190 return _formatIsolateOvercard(isolate.name, free, used);
191 })); 179 }));
192 area.draw(); 180 area.draw();
193 181
194 if (_selected != null) { 182 if (_selected != null) {
195 state.select(_selected); 183 state.select(_selected);
196 if (_selected > 1) { 184 if (_selected > 1) {
197 state.select(_selected + 1); 185 state.select(_selected + 1);
198 } 186 }
199 } 187 }
200 } 188 }
201 189
202 String _formatTimeAxis(num ms) => 190 String _formatTimeAxis(num ms) =>
203 Utils.formatDuration(new Duration(microseconds: ms.toInt()), 191 Utils.formatDuration(new Duration(microseconds: ms.toInt()),
204 precision: DurationComponent.Seconds); 192 precision: DurationComponent.Seconds);
205 193
206 bool _running = false; 194 bool _running = false;
207 195
208 Future _refresh({M.IsolateRef gcIsolate}) async { 196 Future _refresh({M.IsolateRef gcIsolate}) async {
209 if (_running) return; 197 if (_running) return;
210 _running = true; 198 _running = true;
211 final now = new DateTime.now(); 199 final now = new DateTime.now();
212 final start = now.subtract(_window); 200 final start = now.subtract(_window);
213 final vm = await _vms.get(_vm);
214 // The Service classes order isolates from the older to the newer 201 // The Service classes order isolates from the older to the newer
215 final isolates = 202 final isolates =
216 (await Future.wait(vm.isolates.map(_isolates.get))).reversed.toList(); 203 (await Future.wait(_vm.isolates.map(_isolates.get))).reversed.toList();
217 while (_ts.first.isBefore(start)) { 204 while (_ts.first.isBefore(start)) {
218 _ts.removeAt(0); 205 _ts.removeAt(0);
219 _vmSamples.removeAt(0); 206 _vmSamples.removeAt(0);
220 _isolateUsedSamples.removeAt(0); 207 _isolateUsedSamples.removeAt(0);
221 _isolateFreeSamples.removeAt(0); 208 _isolateFreeSamples.removeAt(0);
222 } 209 }
223 210
224 if (_ts.first.isAfter(start)) { 211 if (_ts.first.isAfter(start)) {
225 _ts.insert(0, start); 212 _ts.insert(0, start);
226 _vmSamples.insert(0, _vmSamples.first); 213 _vmSamples.insert(0, _vmSamples.first);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 _isolateUsedSamples.last[index] + _isolateFreeSamples.last[index]; 248 _isolateUsedSamples.last[index] + _isolateFreeSamples.last[index];
262 isolateFreeSample[index] = 0; 249 isolateFreeSample[index] = 0;
263 } else { 250 } else {
264 isolateUsedSample[index] = _used(isolate); 251 isolateUsedSample[index] = _used(isolate);
265 isolateFreeSample[index] = _free(isolate); 252 isolateFreeSample[index] = _free(isolate);
266 } 253 }
267 }); 254 });
268 _isolateUsedSamples.add(isolateUsedSample); 255 _isolateUsedSamples.add(isolateUsedSample);
269 _isolateFreeSamples.add(isolateFreeSample); 256 _isolateFreeSamples.add(isolateFreeSample);
270 257
271 _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]); 258 _vmSamples.add(vm.heapAllocatedMemoryUsage);
272 259
273 _ts.add(now); 260 _ts.add(now);
274 } 261 }
275 final List<int> isolateUsedSample = new List<int>.filled(length, 0); 262 final List<int> isolateUsedSample = new List<int>.filled(length, 0);
276 final List<int> isolateFreeSample = new List<int>.filled(length, 0); 263 final List<int> isolateFreeSample = new List<int>.filled(length, 0);
277 isolates.forEach((M.Isolate isolate) { 264 isolates.forEach((M.Isolate isolate) {
278 _isolateName[isolate.id] = isolate.name; 265 _isolateName[isolate.id] = isolate.name;
279 final index = _isolateIndex[isolate.id]; 266 final index = _isolateIndex[isolate.id];
280 isolateUsedSample[index] = _used(isolate); 267 isolateUsedSample[index] = _used(isolate);
281 isolateFreeSample[index] = _free(isolate); 268 isolateFreeSample[index] = _free(isolate);
282 }); 269 });
283 _isolateUsedSamples.add(isolateUsedSample); 270 _isolateUsedSamples.add(isolateUsedSample);
284 _isolateFreeSamples.add(isolateFreeSample); 271 _isolateFreeSamples.add(isolateFreeSample);
285 272
286 _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]); 273 _vmSamples.add(vm.heapAllocatedMemoryUsage);
287 274
288 _ts.add(now); 275 _ts.add(now);
289 _r.dirty(); 276 _r.dirty();
290 _running = false; 277 _running = false;
291 } 278 }
292 279
293 void _handleEvent(records) => records.forEach((record) { 280 void _handleEvent(records) => records.forEach((record) {
294 if (record is ChartSelectionChangeRecord) { 281 if (record is ChartSelectionChangeRecord) {
295 var selected = record.add; 282 var selected = record.add;
296 if (selected == null) { 283 if (selected == null) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 final index = _isolateIndex[isolateId]; 318 final index = _isolateIndex[isolateId];
332 final name = _isolateName[isolateId]; 319 final name = _isolateName[isolateId];
333 final free = _isolateFreeSamples.last[index]; 320 final free = _isolateFreeSamples.last[index];
334 final used = _isolateUsedSamples.last[index]; 321 final used = _isolateUsedSamples.last[index];
335 final usedStr = Utils.formatSize(used); 322 final usedStr = Utils.formatSize(used);
336 final capacity = free + used; 323 final capacity = free + used;
337 final capacityStr = Utils.formatSize(capacity); 324 final capacityStr = Utils.formatSize(capacity);
338 return '${name} ($usedStr / $capacityStr)'; 325 return '${name} ($usedStr / $capacityStr)';
339 } 326 }
340 327
341 static HtmlElement _formatNativeOvercard(int currentRSS, int heap) => 328 static HtmlElement _formatNativeOvercard(int heap) => new DivElement()
329 ..children = [
342 new DivElement() 330 new DivElement()
331 ..classes = ['hovercard-title']
332 ..text = 'Native',
333 new DivElement()
334 ..classes = ['hovercard-measure', 'hovercard-multi']
343 ..children = [ 335 ..children = [
344 new DivElement() 336 new DivElement()
345 ..classes = ['hovercard-title'] 337 ..classes = ['hovercard-measure-label']
346 ..text = 'Native', 338 ..text = 'Heap',
347 new DivElement() 339 new DivElement()
348 ..classes = ['hovercard-measure', 'hovercard-multi'] 340 ..classes = ['hovercard-measure-value']
349 ..children = [ 341 ..text = Utils.formatSize(heap),
350 new DivElement() 342 ]
351 ..classes = ['hovercard-measure-label'] 343 ];
352 ..text = 'Total Memory Usage',
353 new DivElement()
354 ..classes = ['hovercard-measure-value']
355 ..text = currentRSS != null
356 ? Utils.formatSize(currentRSS)
357 : "unavailable",
358 ],
359 new DivElement()
360 ..classes = ['hovercard-measure', 'hovercard-multi']
361 ..children = [
362 new DivElement()
363 ..classes = ['hovercard-measure-label']
364 ..text = 'Native Heap',
365 new DivElement()
366 ..classes = ['hovercard-measure-value']
367 ..text = heap != null ? Utils.formatSize(heap) : "unavailable",
368 ]
369 ];
370 344
371 static HtmlElement _formatIsolateOvercard(String name, int free, int used) { 345 static HtmlElement _formatIsolateOvercard(String name, int free, int used) {
372 final capacity = free + used; 346 final capacity = free + used;
373 return new DivElement() 347 return new DivElement()
374 ..children = [ 348 ..children = [
375 new DivElement() 349 new DivElement()
376 ..classes = ['hovercard-title'] 350 ..classes = ['hovercard-title']
377 ..text = name, 351 ..text = name,
378 new DivElement() 352 new DivElement()
379 ..classes = ['hovercard-measure', 'hovercard-multi'] 353 ..classes = ['hovercard-measure', 'hovercard-multi']
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 </defs> 427 </defs>
454 '''; 428 ''';
455 429
456 StyleElement get style => new StyleElement() 430 StyleElement get style => new StyleElement()
457 ..text = ''' 431 ..text = '''
458 memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset+1}) 432 memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset+1})
459 path:nth-child(1) { 433 path:nth-child(1) {
460 filter: url(#stroke-grid); 434 filter: url(#stroke-grid);
461 }'''; 435 }''';
462 } 436 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/memory/dashboard.dart ('k') | runtime/observatory/lib/src/elements/vm_view.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698