OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /// This page is not directly reachable from the main Observatory ui. |
| 6 /// It is mainly mented to be used from editors as an integrated tool. |
| 7 /// |
| 8 /// This page mainly targeting developers and not VM experts, so concepts like |
| 9 /// old and new heap are abstracted away. |
| 10 /// |
| 11 /// The page comprises an overall memory usage of the VM from where it is |
| 12 /// possible to select an isolate to deeply analyze. |
| 13 /// See MemoryGraphElement |
| 14 /// |
| 15 /// Once an isolate is selected it is possible to information specific to it. |
| 16 /// See MemoryProfileElement |
| 17 /// |
| 18 /// The logic in this Element is mainly mented to orchestrate the two |
| 19 /// sub-components by means of positioning and message passing. |
| 20 |
| 21 import 'dart:async'; |
| 22 import 'dart:html'; |
| 23 import 'package:observatory/models.dart' as M; |
| 24 import 'package:observatory/src/elements/helpers/nav_bar.dart'; |
| 25 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 26 import 'package:observatory/src/elements/helpers/tag.dart'; |
| 27 import 'package:observatory/src/elements/nav/notify.dart'; |
| 28 import 'package:observatory/src/elements/memory/graph.dart'; |
| 29 import 'package:observatory/src/elements/memory/profile.dart'; |
| 30 |
| 31 class MemoryDashboardElement extends HtmlElement implements Renderable { |
| 32 static const tag = const Tag<MemoryDashboardElement>('memory-dashboard', |
| 33 dependencies: const [ |
| 34 NavNotifyElement.tag, |
| 35 MemoryGraphElement.tag, |
| 36 MemoryProfileElement.tag |
| 37 ]); |
| 38 |
| 39 RenderingScheduler<MemoryDashboardElement> _r; |
| 40 |
| 41 Stream<RenderedEvent<MemoryDashboardElement>> get onRendered => _r.onRendered; |
| 42 |
| 43 M.VMRef _vm; |
| 44 M.IsolateRepository _isolates; |
| 45 M.EditorRepository _editor; |
| 46 M.AllocationProfileRepository _allocations; |
| 47 M.EventRepository _events; |
| 48 M.NotificationRepository _notifications; |
| 49 |
| 50 M.VM get vm => _vm; |
| 51 M.NotificationRepository get notifications => _notifications; |
| 52 |
| 53 factory MemoryDashboardElement( |
| 54 M.VM vm, |
| 55 M.IsolateRepository isolates, |
| 56 M.EditorRepository editor, |
| 57 M.AllocationProfileRepository allocations, |
| 58 M.EventRepository events, |
| 59 M.NotificationRepository notifications, |
| 60 {RenderingQueue queue}) { |
| 61 assert(vm != null); |
| 62 assert(isolates != null); |
| 63 assert(editor != null); |
| 64 assert(allocations != null); |
| 65 assert(events != null); |
| 66 assert(notifications != null); |
| 67 MemoryDashboardElement e = document.createElement(tag.name); |
| 68 e._r = new RenderingScheduler(e, queue: queue); |
| 69 e._vm = vm; |
| 70 e._isolates = isolates; |
| 71 e._editor = editor; |
| 72 e._allocations = allocations; |
| 73 e._events = events; |
| 74 e._notifications = notifications; |
| 75 return e; |
| 76 } |
| 77 |
| 78 MemoryDashboardElement.created() : super.created(); |
| 79 |
| 80 @override |
| 81 attached() { |
| 82 super.attached(); |
| 83 _r.enable(); |
| 84 } |
| 85 |
| 86 @override |
| 87 detached() { |
| 88 super.detached(); |
| 89 _r.disable(notify: true); |
| 90 children = []; |
| 91 } |
| 92 |
| 93 M.IsolateRef _isolate; |
| 94 |
| 95 MemoryGraphElement _graph; |
| 96 |
| 97 void render() { |
| 98 if (_graph == null) { |
| 99 _graph = new MemoryGraphElement(vm, _isolates, _events, queue: _r.queue) |
| 100 ..onIsolateSelected.listen(_onIsolateSelected); |
| 101 } |
| 102 children = [ |
| 103 navBar([new NavNotifyElement(_notifications, queue: _r.queue)]), |
| 104 new DivElement() |
| 105 ..classes = ['content-centered-big'] |
| 106 ..children = [ |
| 107 new HeadingElement.h2()..text = 'Memory Dashboard', |
| 108 new HRElement(), |
| 109 _graph, |
| 110 new HRElement(), |
| 111 ], |
| 112 ]; |
| 113 if (_isolate == null) { |
| 114 children.add(new DivElement() |
| 115 ..classes = ['content-centered-big'] |
| 116 ..children = [new HeadingElement.h1()..text = "No isolate selected"]); |
| 117 } else { |
| 118 final MemoryProfileElement profile = |
| 119 new MemoryProfileElement(_isolate, _editor, _events, _allocations); |
| 120 final ButtonElement reload = new ButtonElement(); |
| 121 final ButtonElement gc = new ButtonElement(); |
| 122 children.addAll([ |
| 123 new DivElement() |
| 124 ..classes = ['content-centered-big'] |
| 125 ..children = [ |
| 126 new HeadingElement.h1() |
| 127 ..children = [ |
| 128 new Text("Isolate ${_isolate.name}"), |
| 129 reload |
| 130 ..classes = ['link', 'big'] |
| 131 ..text = ' ↺ ' |
| 132 ..title = 'Refresh' |
| 133 ..onClick.listen((e) async { |
| 134 gc.disabled = true; |
| 135 reload.disabled = true; |
| 136 await profile.reload(); |
| 137 gc.disabled = false; |
| 138 reload.disabled = false; |
| 139 }), |
| 140 gc |
| 141 ..classes = ['link', 'big'] |
| 142 ..text = ' ♺ ' |
| 143 ..title = 'Collect Garbage' |
| 144 ..onClick.listen((e) async { |
| 145 gc.disabled = true; |
| 146 reload.disabled = true; |
| 147 await profile.reload(gc: true); |
| 148 gc.disabled = false; |
| 149 reload.disabled = false; |
| 150 }), |
| 151 ] |
| 152 ], |
| 153 profile |
| 154 ]); |
| 155 } |
| 156 } |
| 157 |
| 158 void _onIsolateSelected(IsolateSelectedEvent e) { |
| 159 _r.checkAndReact(_isolate, e.isolate); |
| 160 _isolate = e.isolate; |
| 161 } |
| 162 } |
OLD | NEW |