Chromium Code Reviews| Index: pkg/analysis_server/lib/src/status/get_handler.dart |
| diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart |
| index 67263f68de9415bdc68d2c2b9a43f80cc591d54f..b7599a42fd9d814e9df57ead3634ec01d3f03f46 100644 |
| --- a/pkg/analysis_server/lib/src/status/get_handler.dart |
| +++ b/pkg/analysis_server/lib/src/status/get_handler.dart |
| @@ -21,6 +21,7 @@ import 'package:analysis_server/src/services/completion/completion_performance.d |
| import 'package:analysis_server/src/socket_server.dart'; |
| import 'package:analysis_server/src/status/ast_writer.dart'; |
| import 'package:analysis_server/src/status/element_writer.dart'; |
| +import 'package:analysis_server/src/status/memory_use.dart'; |
| import 'package:analysis_server/src/status/validator.dart'; |
| import 'package:analysis_server/src/utilities/average.dart'; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| @@ -258,6 +259,11 @@ class GetHandler { |
| static const String ELEMENT_PATH = '/element'; |
| /** |
| + * The path used to request an analysis of the memory use of the analyzer. |
| + */ |
| + static const String MEMORY_USE_PATH = '/memoryUse'; |
| + |
| + /** |
| * The path used to request an overlay contents. |
| */ |
| static const String OVERLAY_PATH = '/overlay'; |
| @@ -390,6 +396,8 @@ class GetHandler { |
| _returnDiagnosticInfo(request); |
| } else if (path == ELEMENT_PATH) { |
| _returnElement(request); |
| + } else if (path == MEMORY_USE_PATH) { |
| + _returnMemoryUsage(request); |
| } else if (path == OVERLAY_PATH) { |
| _returnOverlayContents(request); |
| } else if (path == OVERLAYS_PATH) { |
| @@ -1644,6 +1652,55 @@ class GetHandler { |
| }); |
| } |
| + void _returnMemoryUsage(HttpRequest request) { |
| + _writeResponse(request, (StringBuffer buffer) { |
| + _writePage(buffer, 'Analysis Server - Memory Use', [], |
| + (StringBuffer buffer) { |
| + AnalysisServer server = _server.analysisServer; |
| + MemoryUseData data = new MemoryUseData(); |
| + data.processAnalysisServer(server); |
| + Map<Type, HashSet> instances = data.instances; |
| + List<Type> classNames = instances.keys.toList(); |
|
scheglov
2016/07/11 15:27:49
These are not names, but types.
Just in case if th
Brian Wilkerson
2016/07/11 17:26:36
It was accidental, thanks. Done.
|
| + classNames.sort((Type left, Type right) => |
| + left.toString().compareTo(right.toString())); |
| + |
| + buffer.write('<h3>Instance Counts (reachable from contexts)</h3>'); |
| + buffer.write('<table>'); |
| + _writeRow(buffer, ['Count', 'Class name'], header: true); |
| + classNames.forEach((Type type) { |
| + _writeRow(buffer, [instances[type].length, type], |
| + classes: ['right', null]); |
| + }); |
| + buffer.write('</table>'); |
| + |
| + void writeCountMap(String title, Map<Type, int> counts) { |
| + List<Type> classNames = counts.keys.toList(); |
| + classNames.sort((Type left, Type right) => |
| + left.toString().compareTo(right.toString())); |
| + |
| + buffer.write('<h3>$title</h3>'); |
| + buffer.write('<table>'); |
| + _writeRow(buffer, ['Count', 'Class name'], header: true); |
| + classNames.forEach((Type type) { |
| + _writeRow(buffer, [counts[type], type], classes: ['right', null]); |
| + }); |
| + buffer.write('</table>'); |
| + } |
| + writeCountMap('Directly Held AST Nodes', data.directNodeCounts); |
| + writeCountMap('Indirectly Held AST Nodes', data.indirectNodeCounts); |
| + writeCountMap('Directly Held Elements', data.elementCounts); |
| + |
| + buffer.write('<h3>Other Data</h3>'); |
| + buffer.write('<p>'); |
| + buffer.write(data.uniqueTargetedResults.length); |
| + buffer.write(' non-equal TargetedResults</p>'); |
| + buffer.write('<p>'); |
| + buffer.write(data.uniqueLSUs.length); |
| + buffer.write(' non-equal LibrarySpecificUnits</p>'); |
| + }); |
| + }); |
| + } |
| + |
| void _returnOverlayContents(HttpRequest request) { |
| String path = request.requestedUri.queryParameters[PATH_PARAM]; |
| if (path == null) { |
| @@ -2228,6 +2285,7 @@ class GetHandler { |
| int length = keys.length; |
| buffer.write('{'); |
| for (int i = 0; i < length; i++) { |
| + buffer.write('<br>'); |
| String key = keys[i]; |
| if (i > 0) { |
| buffer.write(', '); |
| @@ -2236,7 +2294,7 @@ class GetHandler { |
| buffer.write(' = '); |
| buffer.write(map[key]); |
| } |
| - buffer.write('}'); |
| + buffer.write('<br>}'); |
| } |
| /** |
| @@ -2289,6 +2347,7 @@ class GetHandler { |
| 'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}'); |
| buffer.write('td.column {vertical-align: top; width: 50%;}'); |
| buffer.write('td.right {text-align: right;}'); |
| + buffer.write('th {text-align: left;}'); |
| buffer.write('</style>'); |
| buffer.write('</head>'); |
| @@ -2447,6 +2506,9 @@ class GetHandler { |
| buffer.write('<p>'); |
| buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'General diagnostics')); |
| buffer.write('</p>'); |
| + buffer.write('<p>'); |
| + buffer.write(makeLink(MEMORY_USE_PATH, {}, 'Memory usage')); |
| + buffer.write(' <small>(long running)</small></p>'); |
| }, (StringBuffer buffer) { |
| _writeSubscriptionList(buffer, ServerService.VALUES, services); |
| }); |