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

Side by Side Diff: pkg/compiler/tool/track_memory.dart

Issue 1384833002: add tool to track memory watermark (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 /// A script to track the high water-mark of memory usage of an application.
6 /// To monitor how much memory dart2js is using, run dart2js as follows:
7 ///
8 /// DART_VM_OPTIONS=--observe dart2js ...
9 ///
10 /// and run this script immediately after.
11 library compiler.tool.track_memory;
12
13 import 'dart:math' show max;
14 import 'dart:io';
15 import 'dart:async';
16
17 import 'dart:convert';
18
19 /// Socket to connect to the vm observatory service.
20 WebSocket socket;
21
22 main() async {
23 _printHeader();
24 _showProgress(0, 0, 0, 0);
25 try {
26 socket = await WebSocket.connect('ws://localhost:8181/ws');
sra1 2015/10/05 17:04:58 TODO: you might need to change the port if another
Siggi Cherem (dart-lang) 2015/10/05 17:19:44 Done. Just made it an arg which defaults to 8181
27 socket.listen(_handleResponse);
28 await _resumeMainIsolateIfPaused();
29 _streamListen('GC');
30 _streamListen('Isolate');
31 _streamListen('Debug');
32 } on SocketException catch (e) {
33 // TODO(sigmund): add better error messages, maybe option to retry.
34 print('\n${_RED}error${_NONE}: $e');
35 }
36 }
37
38 /// Internal counter for request ids.
39 int _requestId = 0;
40 Map _pendingResponses = {};
41
42 /// Subscribe to listen to a vm service data stream.
43 _streamListen(String streamId) =>
44 _sendMessage("streamListen", {"streamId": "$streamId"});
45
46 /// Tell the vm service to resume a specific isolate.
47 _resumeIsolate(String isolateId) =>
48 _sendMessage("resume", {"isolateId": "$isolateId"});
49
50 /// Resumes the main isolate if it was paused on start.
51 _resumeMainIsolateIfPaused() async {
52 var vm = await _sendMessage('getVM');
53 var isolateId = vm["isolates"][0]["id"];
54 var isolate = await _sendMessage('getIsolate', {'isolateId': isolateId});
sra1 2015/10/05 17:04:58 Some strings are 'x' others "x". I assume the inte
Siggi Cherem (dart-lang) 2015/10/05 17:19:44 Good point - yeah, I had started with ', then copi
55 bool isPaused = isolate["pauseEvent"]["kind"] == "PauseStart";
56 if (isPaused) _resumeIsolate(isolateId);
57 }
58
59 /// Send a message to the vm service.
60 Future _sendMessage(String method, [Map args= const {}]) {
61 var id = _requestId++;
62 _pendingResponses[id] = new Completer();
63 socket.add(JSON.encode({
64 "jsonrpc": "2.0",
65 "id": "$id",
66 "method": "$method",
67 "params": args,
68 }));
69 return _pendingResponses[id].future;
70 }
71
72 /// Handle all responses
73 _handleResponse(String s) {
74 var json = JSON.decode(s);
75 if (json['method'] != "streamNotify") {
76 var id = json['id'];
77 if (id is String) id = int.parse(id);
78 if (id == null || !_pendingResponses.containsKey(id)) return;
79 _pendingResponses.remove(id).complete(json["result"]);
80 return;
81 }
82
83 // isolate pauses on exit automatically. We detect this to stop and exit.
84 if (json["params"]["streamId"] == "Debug") {
85 _handleDebug(json);
86 } else if (json["params"]["streamId"] == "Isolate") {
87 _handleIsolate(json);
88 } else if (json["params"]["streamId"] == "GC") {
89 _handleGC(json);
90 }
91 }
92
93 /// Handle a `Debug` notification.
94 _handleDebug(Map json) {
95 var isolateId = json["params"]["event"]["isolate"]["id"];
96 if (json["params"]["event"]["kind"] == "PauseStart") {
97 _resumeIsolate(isolateId);
98 } if (json["params"]["event"]["kind"] == "PauseExit") {
99 _resumeIsolate(isolateId);
100 }
101 }
102
103 /// Handle a `Isolate` notification.
104 _handleIsolate(Map json) {
105 if (json["params"]["event"]["kind"] == "IsolateExit") {
106 print('');
107 socket.close();
108 }
109 }
110
111 /// Handle a `GC` notification.
112 _handleGC(Map json) {
113 // print(new JsonEncoder.withIndent(" ").convert(json));
114 var event = json["params"]["event"];
115 var newUsed = event["new"]["used"];
116 var newCapacity = event["new"]["capacity"];
117 var oldUsed = event["old"]["used"];
118 var oldCapacity = event["old"]["capacity"];
119 _showProgress(newUsed, newCapacity, oldUsed, oldCapacity);
120 }
121
122 int lastNewUsed = 0;
123 int lastOldUsed = 0;
124 int lastMaxUsed = 0;
125 int lastNewCapacity = 0;
126 int lastOldCapacity = 0;
127 int lastMaxCapacity = 0;
128
129 /// Shows a status line with use/capacity numbers for new/old/total/max,
130 /// highlighting in red when capacity increases, and in green when it decreases.
131 _showProgress(newUsed, newCapacity, oldUsed, oldCapacity) {
132 var sb = new StringBuffer();
133 sb.write('\r '); // replace the status-line in place
134 _writeNumber(sb, lastNewUsed, newUsed);
135 _writeNumber(sb, lastNewCapacity, newCapacity, color: true);
136
137 sb.write(' | ');
138 _writeNumber(sb, lastOldUsed, oldUsed);
139 _writeNumber(sb, lastOldCapacity, oldCapacity, color: true);
140
141 sb.write(' | ');
142 _writeNumber(sb, lastNewUsed + lastOldUsed, newUsed + oldUsed);
143 _writeNumber(sb, lastNewCapacity + lastOldCapacity, newCapacity + oldCapacity,
144 color: true);
145
146 sb.write(' | ');
147 var maxUsed = max(lastMaxUsed, newUsed + oldUsed);
148 var maxCapacity = max(lastMaxCapacity, newCapacity + oldCapacity);
149 _writeNumber(sb, lastMaxUsed, maxUsed);
150 _writeNumber(sb, lastMaxCapacity, maxCapacity, color: true);
151 stdout.write('$sb');
152
153 lastNewUsed = newUsed;
154 lastOldUsed = oldUsed;
155 lastMaxUsed = maxUsed;
156 lastNewCapacity = newCapacity;
157 lastOldCapacity = oldCapacity;
158 lastMaxCapacity = maxCapacity;
159 }
160
161 const mega = 1024 * 1024;
162 _writeNumber(sb, before, now, {color: false}) {
163 if (color) sb.write(before < now ? _RED : before > now ? _GREEN : '');
164 var string;
165 if (now < 1024) {
166 string = ' ${now}b';
167 } else if (now < mega) {
168 string = ' ${(now/1024).toStringAsFixed(0)}K';
169 } else {
170 string = ' ${(now/mega).toStringAsFixed(1)}M';
171 }
172 if (string.length < 10) string = '${" " * (8 - string.length)}$string';
173 sb.write(string);
174 if (color) sb.write(before != now ? _NONE : '');
175 return before > now;
176 }
177
178 _printHeader() {
179 print('''
180 Memory usage:
181 new generation | old generation | total | max
182 in-use/capacity | in-use/capacity | in-use/capacity | in-use/capacity ''');
183 }
184
185 const _RED = "\x1b[31m";
186 const _GREEN = "\x1b[32m";
187 const _NONE = "\x1b[0m";
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698