UME: 内存查看
今天我们要看一下内存查看功能是如何实现的, 在看代码之前先看下效果是什么样的
那么今天就主要分三个部分来看, 分别是VM Info、Memory Info及Class的内存信息,今天的主要代码都在flutter_ume_kit_perf模块中,页面代码在memory_info_page.dart中,主要逻辑都在memory_service.dart中
VM Info
通过ServiceWrapper来获取VMService
ServiceWrapper昨天应该就已经见过了,昨天也是通过这个自建类获取的VM信息从而获取的path
通过VMService拿到VM,VM中就包含Pid、CPU、Verison这些信息
VM中的信息
{
type: VM,
name: vm,
architectureBits: 64,
hostCPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz,
operatingSystem: ios,
targetCPU: x64,
version: 2.15.0-42.0.dev (dev) (Sun Aug 22 13:00:21 2021 -0700) on "ios_x64",
pid: 2480,
startTime: 1636098434474,
isolates: [
{type: @Isolate, id: isolates/290036810778119, number: 290036810778119, name: main, isSystemIsolate: false}
],
isolateGroups: [
{type: @IsolateGroup, id: isolateGroups/12365199645329027070, number: 12365199645329027070, name: main.dart, isSystemIsolateGroup: false}
],
systemIsolates: [
{type: @Isolate, id: isolates/2845908153139319, number: 2845908153139319, name: vm-service, isSystemIsolate: true}
],
systemIsolateGroups: [
{type: @IsolateGroup, id: isolateGroups/5190594318708735198, number: 5190594318708735198, name: vm-service, isSystemIsolateGroup: true}
]
}
Memory Info
Memory信息同样是通过vm调用getMemoryUsage
方法获取内存分配信息,将其中的members遍历筛选出bytes>0和instances>0的数据返回
{
type: MemoryUsage,
externalUsage: 5668480,
heapCapacity: 134545408,
heapUsage: 115805296
}
Class的内存信息
通过vm的getAllocationProfile
方法获取分配对象信息,通过members属性来获取到每个class所占用的堆信息, 并将list进行排序,将list中不是以'_'开头的name进行存储,用于显示非私有类
void _heapInfoList(List<ClassHeapStats> list) {
allClasses = list;
allClasses.sort((a, b) => b.accumulatedSize!.compareTo(a.accumulatedSize!));
infoList = allClasses
.where((element) => !element.classRef!.name!.startsWith("_"))
.toList();
}
infolist中的ClassHeapStats
存储着我们需要的信息,ClassHeapStats
主要包含以下字段
classRef: 类信息
accumulatedSize: 自上次重置累加器以来为类实例分配的字节数
bytesCurrent:当前内存大小
instancesAccumulated:自上次累加器重置以来已分配的类实例数
int? instancesCurrent:当前实例数量
我们可以看到list中显示Size、Count及classname就是通过accumulatedSize
、instancesAccumulated
及classRef
info详情
info详情页里的信息主要是通过上面的classRef的id来获取到class,在class中遍历fields
及functions
void getClassDetailInfo(
String classId, Function(ClsModel?) completion) async {
Class cls = await serviceWrapper.getObject(classId) as Class;
ClsModel? _clsModel;
if (cls.fields != null && cls.fields!.isNotEmpty) {
List<Property> properties = [];
List<String> functions = [];
cls.fields?.forEach((fieldRef) {
Property _property = Property(fieldRef.isConst, fieldRef.isStatic,
fieldRef.isFinal, fieldRef.declaredType!.name, fieldRef.name);
properties.add(_property);
});
for (var fucRef in cls.functions!) {
String? code;
Obj func = await serviceWrapper.getObject(fucRef.id!);
if (func is Func) {
code = func.code!.name;
if (func.code!.name!.contains("[Stub]")) {
continue;
}
code = code!.replaceAll('[Unoptimized] ', '');
code = code.replaceAll('[Optimized] ', '');
functions.add(code);
}
}
_clsModel = ClsModel(propeties: properties, functions: functions);
}
好了今天的源码查看就到这了, 作为Flutter届的一个小学生,希望大家多多指教,有问题的地方一起讨论
转载自:https://juejin.cn/post/7027026275969531911