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

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

Issue 2996803002: Add current rss and embedder name to Observatory (Closed)
Patch Set: Managing null currentRSS in graph tooltip 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.VM _vm; 44 M.VMRef _vm;
45 M.VMRepository _vms;
45 M.IsolateRepository _isolates; 46 M.IsolateRepository _isolates;
46 M.EventRepository _events; 47 M.EventRepository _events;
47 StreamSubscription _onGCSubscription; 48 StreamSubscription _onGCSubscription;
48 StreamSubscription _onResizeSubscription; 49 StreamSubscription _onResizeSubscription;
49 StreamSubscription _onConnectionClosedSubscription; 50 StreamSubscription _onConnectionClosedSubscription;
50 Timer _onTimer; 51 Timer _onTimer;
51 52
52 M.VM get vm => _vm; 53 M.VMRef get vm => _vm;
53 54
54 factory MemoryGraphElement( 55 factory MemoryGraphElement(M.VMRef vm, M.VMRepository vms,
55 M.VM vm, M.IsolateRepository isolates, M.EventRepository events, 56 M.IsolateRepository isolates, M.EventRepository events,
56 {RenderingQueue queue}) { 57 {RenderingQueue queue}) {
57 assert(vm != null); 58 assert(vm != null);
59 assert(vms != null);
58 assert(isolates != null); 60 assert(isolates != null);
59 assert(events != null); 61 assert(events != null);
60 MemoryGraphElement e = document.createElement(tag.name); 62 MemoryGraphElement e = document.createElement(tag.name);
61 e._r = new RenderingScheduler(e, queue: queue); 63 e._r = new RenderingScheduler(e, queue: queue);
62 e._vm = vm; 64 e._vm = vm;
65 e._vms = vms;
63 e._isolates = isolates; 66 e._isolates = isolates;
64 e._events = events; 67 e._events = events;
65 return e; 68 return e;
66 } 69 }
67 70
68 MemoryGraphElement.created() : super.created() { 71 MemoryGraphElement.created() : super.created() {
69 final now = new DateTime.now(); 72 final now = new DateTime.now();
70 var sample = now.subtract(_window); 73 var sample = now.subtract(_window);
71 while (sample.isBefore(now)) { 74 while (sample.isBefore(now)) {
72 _ts.add(sample); 75 _ts.add(sample);
73 _vmSamples.add(0); 76 _vmSamples.add(<int>[0, 0]);
74 _isolateUsedSamples.add([]); 77 _isolateUsedSamples.add([]);
75 _isolateFreeSamples.add([]); 78 _isolateFreeSamples.add([]);
76 sample = sample.add(_period); 79 sample = sample.add(_period);
77 } 80 }
78 _ts.add(now); 81 _ts.add(now);
79 _vmSamples.add(0); 82 _vmSamples.add(<int>[0, 0]);
80 _isolateUsedSamples.add([]); 83 _isolateUsedSamples.add([]);
81 _isolateFreeSamples.add([]); 84 _isolateFreeSamples.add([]);
82 } 85 }
83 86
84 static const Duration _period = const Duration(seconds: 2); 87 static const Duration _period = const Duration(seconds: 2);
85 static const Duration _window = const Duration(minutes: 2); 88 static const Duration _window = const Duration(minutes: 2);
86 89
87 @override 90 @override
88 attached() { 91 attached() {
89 super.attached(); 92 super.attached();
(...skipping 12 matching lines...) Expand all
102 super.detached(); 105 super.detached();
103 _r.disable(notify: true); 106 _r.disable(notify: true);
104 children = []; 107 children = [];
105 _onGCSubscription.cancel(); 108 _onGCSubscription.cancel();
106 _onConnectionClosedSubscription.cancel(); 109 _onConnectionClosedSubscription.cancel();
107 _onResizeSubscription.cancel(); 110 _onResizeSubscription.cancel();
108 _onTimer.cancel(); 111 _onTimer.cancel();
109 } 112 }
110 113
111 final List<DateTime> _ts = <DateTime>[]; 114 final List<DateTime> _ts = <DateTime>[];
112 final List<int> _vmSamples = <int>[]; 115 final List<List<int>> _vmSamples = <List<int>>[];
113 final List<M.IsolateRef> _seenIsolates = <M.IsolateRef>[]; 116 final List<M.IsolateRef> _seenIsolates = <M.IsolateRef>[];
114 final List<List<int>> _isolateUsedSamples = <List<int>>[]; 117 final List<List<int>> _isolateUsedSamples = <List<int>>[];
115 final List<List<int>> _isolateFreeSamples = <List<int>>[]; 118 final List<List<int>> _isolateFreeSamples = <List<int>>[];
116 final Map<String, int> _isolateIndex = <String, int>{}; 119 final Map<String, int> _isolateIndex = <String, int>{};
117 final Map<String, String> _isolateName = <String, String>{}; 120 final Map<String, String> _isolateName = <String, String>{};
118 121
119 var _selected; 122 var _selected;
120 var _previewed; 123 var _previewed;
121 var _hovered; 124 var _hovered;
122 125
(...skipping 16 matching lines...) Expand all
139 formatter: _formatTimeAxis, type: ChartColumnSpec.TYPE_NUMBER), 142 formatter: _formatTimeAxis, type: ChartColumnSpec.TYPE_NUMBER),
140 new ChartColumnSpec(label: 'Native', formatter: Utils.formatSize) 143 new ChartColumnSpec(label: 'Native', formatter: Utils.formatSize)
141 ]..addAll(_isolateName.keys.expand((id) => [ 144 ]..addAll(_isolateName.keys.expand((id) => [
142 new ChartColumnSpec(formatter: Utils.formatSize), 145 new ChartColumnSpec(formatter: Utils.formatSize),
143 new ChartColumnSpec(label: _label(id), formatter: Utils.formatSize) 146 new ChartColumnSpec(label: _label(id), formatter: Utils.formatSize)
144 ])); 147 ]));
145 // The stacked line chart sorts from top to bottom 148 // The stacked line chart sorts from top to bottom
146 final rows = new List.generate(_ts.length, (sampleIndex) { 149 final rows = new List.generate(_ts.length, (sampleIndex) {
147 final free = _isolateFreeSamples[sampleIndex]; 150 final free = _isolateFreeSamples[sampleIndex];
148 final used = _isolateUsedSamples[sampleIndex]; 151 final used = _isolateUsedSamples[sampleIndex];
152 final isolates = _isolateIndex.keys.expand((key) {
153 final isolateIndex = _isolateIndex[key];
154 return <int>[free[isolateIndex], used[isolateIndex]];
155 });
149 return [ 156 return [
150 _ts[sampleIndex].difference(now).inMicroseconds, 157 _ts[sampleIndex].difference(now).inMicroseconds,
151 _vmSamples[sampleIndex] 158 _vmSamples[sampleIndex][1]
152 ]..addAll(_isolateIndex.keys.expand((key) { 159 ]..addAll(isolates);
153 final isolateIndex = _isolateIndex[key];
154 return [free[isolateIndex], used[isolateIndex]];
155 }));
156 }); 160 });
157 161
158 final scale = new LinearScale()..domain = [(-_window).inMicroseconds, 0]; 162 final scale = new LinearScale()..domain = [(-_window).inMicroseconds, 0];
159 final axisConfig = new ChartAxisConfig()..scale = scale; 163 final axisConfig = new ChartAxisConfig()..scale = scale;
160 final sMemory = 164 final sMemory =
161 new ChartSeries('Memory', series, new StackedLineChartRenderer()); 165 new ChartSeries('Memory', series, new StackedLineChartRenderer());
162 final config = new ChartConfig([sMemory], [0]) 166 final config = new ChartConfig([sMemory], [0])
163 ..legend = new ChartLegend(legend) 167 ..legend = new ChartLegend(legend)
164 ..registerDimensionAxis(0, axisConfig); 168 ..registerDimensionAxis(0, axisConfig);
165 config.minimumSize = new Rect(rect.width, rect.height); 169 config.minimumSize = new Rect(rect.width, rect.height);
(...skipping 22 matching lines...) Expand all
188 Utils.formatDuration(new Duration(microseconds: ms.toInt()), 192 Utils.formatDuration(new Duration(microseconds: ms.toInt()),
189 precision: DurationComponent.Seconds); 193 precision: DurationComponent.Seconds);
190 194
191 bool _running = false; 195 bool _running = false;
192 196
193 Future _refresh({M.IsolateRef gcIsolate}) async { 197 Future _refresh({M.IsolateRef gcIsolate}) async {
194 if (_running) return; 198 if (_running) return;
195 _running = true; 199 _running = true;
196 final now = new DateTime.now(); 200 final now = new DateTime.now();
197 final start = now.subtract(_window); 201 final start = now.subtract(_window);
202 final vm = await _vms.get(_vm);
198 // The Service classes order isolates from the older to the newer 203 // The Service classes order isolates from the older to the newer
199 final isolates = 204 final isolates =
200 (await Future.wait(_vm.isolates.map(_isolates.get))).reversed.toList(); 205 (await Future.wait(vm.isolates.map(_isolates.get))).reversed.toList();
201 while (_ts.first.isBefore(start)) { 206 while (_ts.first.isBefore(start)) {
202 _ts.removeAt(0); 207 _ts.removeAt(0);
203 _vmSamples.removeAt(0); 208 _vmSamples.removeAt(0);
204 _isolateUsedSamples.removeAt(0); 209 _isolateUsedSamples.removeAt(0);
205 _isolateFreeSamples.removeAt(0); 210 _isolateFreeSamples.removeAt(0);
206 } 211 }
207 212
208 if (_ts.first.isAfter(start)) { 213 if (_ts.first.isAfter(start)) {
209 _ts.insert(0, start); 214 _ts.insert(0, start);
210 _vmSamples.insert(0, _vmSamples.first); 215 _vmSamples.insert(0, _vmSamples.first);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 _isolateUsedSamples.last[index] + _isolateFreeSamples.last[index]; 250 _isolateUsedSamples.last[index] + _isolateFreeSamples.last[index];
246 isolateFreeSample[index] = 0; 251 isolateFreeSample[index] = 0;
247 } else { 252 } else {
248 isolateUsedSample[index] = _used(isolate); 253 isolateUsedSample[index] = _used(isolate);
249 isolateFreeSample[index] = _free(isolate); 254 isolateFreeSample[index] = _free(isolate);
250 } 255 }
251 }); 256 });
252 _isolateUsedSamples.add(isolateUsedSample); 257 _isolateUsedSamples.add(isolateUsedSample);
253 _isolateFreeSamples.add(isolateFreeSample); 258 _isolateFreeSamples.add(isolateFreeSample);
254 259
255 _vmSamples.add(vm.heapAllocatedMemoryUsage); 260 _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]);
256 261
257 _ts.add(now); 262 _ts.add(now);
258 } 263 }
259 final List<int> isolateUsedSample = new List<int>.filled(length, 0); 264 final List<int> isolateUsedSample = new List<int>.filled(length, 0);
260 final List<int> isolateFreeSample = new List<int>.filled(length, 0); 265 final List<int> isolateFreeSample = new List<int>.filled(length, 0);
261 isolates.forEach((M.Isolate isolate) { 266 isolates.forEach((M.Isolate isolate) {
262 _isolateName[isolate.id] = isolate.name; 267 _isolateName[isolate.id] = isolate.name;
263 final index = _isolateIndex[isolate.id]; 268 final index = _isolateIndex[isolate.id];
264 isolateUsedSample[index] = _used(isolate); 269 isolateUsedSample[index] = _used(isolate);
265 isolateFreeSample[index] = _free(isolate); 270 isolateFreeSample[index] = _free(isolate);
266 }); 271 });
267 _isolateUsedSamples.add(isolateUsedSample); 272 _isolateUsedSamples.add(isolateUsedSample);
268 _isolateFreeSamples.add(isolateFreeSample); 273 _isolateFreeSamples.add(isolateFreeSample);
269 274
270 _vmSamples.add(vm.heapAllocatedMemoryUsage); 275 _vmSamples.add(<int>[vm.currentRSS, vm.heapAllocatedMemoryUsage]);
271 276
272 _ts.add(now); 277 _ts.add(now);
273 _r.dirty(); 278 _r.dirty();
274 _running = false; 279 _running = false;
275 } 280 }
276 281
277 void _handleEvent(records) => records.forEach((record) { 282 void _handleEvent(records) => records.forEach((record) {
278 if (record is ChartSelectionChangeRecord) { 283 if (record is ChartSelectionChangeRecord) {
279 var selected = record.add; 284 var selected = record.add;
280 if (selected == null) { 285 if (selected == null) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 Element _formatNativeOvercard(int row) => new DivElement() 330 Element _formatNativeOvercard(int row) => new DivElement()
326 ..children = [ 331 ..children = [
327 new DivElement() 332 new DivElement()
328 ..classes = ['hovercard-title'] 333 ..classes = ['hovercard-title']
329 ..text = 'Native', 334 ..text = 'Native',
330 new DivElement() 335 new DivElement()
331 ..classes = ['hovercard-measure', 'hovercard-multi'] 336 ..classes = ['hovercard-measure', 'hovercard-multi']
332 ..children = [ 337 ..children = [
333 new DivElement() 338 new DivElement()
334 ..classes = ['hovercard-measure-label'] 339 ..classes = ['hovercard-measure-label']
335 ..text = 'Heap', 340 ..text = 'Total Memory Usage',
336 new DivElement() 341 new DivElement()
337 ..classes = ['hovercard-measure-value'] 342 ..classes = ['hovercard-measure-value']
338 ..text = Utils.formatSize(_vmSamples[row]), 343 ..text = _vmSamples[row][0] != null
344 ? "unavailable"
345 : Utils.formatSize(_vmSamples[row][0]),
346 ],
347 new DivElement()
348 ..classes = ['hovercard-measure', 'hovercard-multi']
349 ..children = [
350 new DivElement()
351 ..classes = ['hovercard-measure-label']
352 ..text = 'Native Heap',
353 new DivElement()
354 ..classes = ['hovercard-measure-value']
355 ..text = Utils.formatSize(_vmSamples[row][1]),
339 ] 356 ]
340 ]; 357 ];
341 358
342 Element _formatIsolateOvercard(String isolateId, int row) { 359 Element _formatIsolateOvercard(String isolateId, int row) {
343 final index = _isolateIndex[isolateId]; 360 final index = _isolateIndex[isolateId];
344 final free = _isolateFreeSamples[row][index]; 361 final free = _isolateFreeSamples[row][index];
345 final used = _isolateUsedSamples[row][index]; 362 final used = _isolateUsedSamples[row][index];
346 final capacity = free + used; 363 final capacity = free + used;
347 return new DivElement() 364 return new DivElement()
348 ..children = [ 365 ..children = [
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 </defs> 444 </defs>
428 '''; 445 ''';
429 446
430 StyleElement get style => new StyleElement() 447 StyleElement get style => new StyleElement()
431 ..text = ''' 448 ..text = '''
432 memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset+1}) 449 memory-graph svg .stacked-line-rdr-line:nth-child(2n+${_offset+1})
433 path:nth-child(1) { 450 path:nth-child(1) {
434 filter: url(#stroke-grid); 451 filter: url(#stroke-grid);
435 }'''; 452 }''';
436 } 453 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698