d4t_formulas/.pub-cache/hosted/pub.dev/analyzer-7.7.1/example/ddd11.dart

165 lines
4.8 KiB
Dart
Raw Normal View History

import 'dart:developer' as developer;
import 'dart:io' as io;
import 'dart:typed_data';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:heap_snapshot/analysis.dart';
import 'package:heap_snapshot/format.dart';
import 'package:vm_service/vm_service.dart';
Future<void> main() async {
timer.start();
var resourceProvider = OverlayResourceProvider(
PhysicalResourceProvider.INSTANCE,
);
var analyzerPath = '/Users/scheglov/Source/Dart/sdk.git/sdk/pkg/analyzer';
var filePath = '$analyzerPath/lib/src/dart/element/element.dart';
var collection = AnalysisContextCollectionImpl(
resourceProvider: resourceProvider,
includedPaths: [analyzerPath],
);
var analysisDriver = collection.contextFor(filePath).driver;
analysisDriver.priorityFiles = [filePath];
timer.reset();
await analysisDriver.getResolvedUnit(filePath);
print('[+${timer.elapsedMilliseconds} ms] Get resolved unit');
var bytes = _getHeapSnapshot();
timer.reset();
var graph = HeapSnapshotGraph.fromChunks([
bytes.buffer.asByteData(bytes.offsetInBytes, bytes.length),
]);
print('[+${timer.elapsedMilliseconds} ms] Create HeapSnapshotGraph');
var analysis = Analysis(graph);
// Computing reachable objects takes some time.
timer.reset();
analysis.reachableObjects;
print('[+${timer.elapsedMilliseconds} ms] Compute reachable objects');
print('');
{
var measure = analysis.measureObjects(analysis.reachableObjects);
print('reachableObjects');
print(' count: ${measure.count}');
print(' size: ${formatBytes(measure.size)}');
}
// It is interesting to see all reachable objects.
{
print('Reachable objects');
var objects = analysis.reachableObjects;
analysis.printObjectStats(objects, maxLines: 100);
}
{
print('\n\n');
print('Tokens');
var classSet = analysis.classByPredicate((e) {
return e.name.endsWith('Token') || e.name.endsWith('TokenImpl');
});
var objects = analysis.filterByClassId(analysis.reachableObjects, classSet);
analysis.printObjectStats(objects, maxLines: 100);
print('\n\n');
print('Tokens retainers');
analysis.printRetainers(objects, maxEntries: 10);
}
}
final Stopwatch timer = Stopwatch();
Future pumpEventQueue([int times = 5000]) {
if (times == 0) return Future.value();
return Future.delayed(Duration.zero, () => pumpEventQueue(times - 1));
}
Uint8List _getHeapSnapshot() {
timer.reset();
var tmpDir = io.Directory.systemTemp.createTempSync('analyzer_heap');
try {
var snapshotFile = io.File('${tmpDir.path}/0.heap_snapshot');
developer.NativeRuntime.writeHeapSnapshotToFile(snapshotFile.path);
print('[+${timer.elapsedMilliseconds} ms] Write heap snapshot');
timer.reset();
var bytes = snapshotFile.readAsBytesSync();
print(
'[+${timer.elapsedMilliseconds} ms] '
'Read heap snapshot, ${bytes.length ~/ (1024 * 1024)} MB',
);
return bytes;
} finally {
tmpDir.deleteSync(recursive: true);
}
}
class _ObjectSetMeasure {
final int count;
final int size;
_ObjectSetMeasure({required this.count, required this.size});
}
extension on Analysis {
IntSet classByPredicate(bool Function(HeapSnapshotClass) predicate) {
var allClasses = graph.classes;
var classSet = SpecializedIntSet(allClasses.length);
for (var class_ in allClasses) {
if (predicate(class_)) {
classSet.add(class_.classId);
}
}
return classSet;
}
// ignore: unused_element
IntSet filterByClass(
IntSet objectIds, {
required Uri libraryUri,
required String name,
}) {
var cid =
graph.classes.singleWhere((class_) {
return class_.libraryUri == libraryUri && class_.name == name;
}).classId;
return filter(objectIds, (object) => object.classId == cid);
}
_ObjectSetMeasure measureObjects(IntSet objectIds) {
var stats = generateObjectStats(objectIds);
var totalSize = 0;
var totalCount = 0;
for (var class_ in stats.classes) {
totalCount += stats.counts[class_.classId];
totalSize += stats.sizes[class_.classId];
}
return _ObjectSetMeasure(count: totalCount, size: totalSize);
}
void printObjectStats(IntSet objectIds, {int maxLines = 20}) {
var stats = generateObjectStats(objectIds);
print(formatHeapStats(stats, maxLines: maxLines));
print('');
}
void printRetainers(IntSet objectIds, {int maxEntries = 3}) {
var paths = retainingPathsOf(objectIds, 20);
for (int i = 0; i < paths.length; ++i) {
if (i >= maxEntries) break;
var path = paths[i];
print('There are ${path.count} retaining paths of');
print(formatRetainingPath(graph, paths[i]));
print('');
}
}
}