如何在Flutter中查找内存泄漏?

dzhpxtsq  于 2022-11-30  发布在  Flutter
关注(0)|答案(3)|浏览(257)

我需要在Flutter中找到内存泄漏。如何找到它们?以及如何为测试创建内存泄漏?

wwwo4jvm

wwwo4jvm1#

Am implemented Memory leack testing in android studio ide.
Step - 1 : Connect your device with android studio and run your application on your device.
Step - 2 : Go to View -> Tool Windows -> Flutter Performance
Step - 3 : Bottom of the window "Open Dev Tools" option will be there, click on it. It will be navigate into new window of your browser. See below image for more details :

Step - 4 : To follow below steps as per screen shot , you can able to see object size and details.Which are caused memory leakages. First Select "Memory" from available menus than you can able to see below ui.

1. Click on settings icon

 2. Select "Dart" and "Flutter"  from checkbox.

 3. Click on "Apply" button.

Step - 5 : This is final step, now you can able to see memory leaking info.

1. Click on "Snapshot" it will be collect and display object list in bottom of the window.
2. Click on search icon and Here you can see those classes which objects are not destroyed. Suppose am selected "ApiRepository.dart" class and instance will be available in memory ,so that details are visible in window. If multiple objects created than you can see here the total no. of instance and total size.

Step - 6 : You can able to call Garbage Collector manually by using "GC" . You can anytime Reset and get latest snapshot using "Reset" and "Snapshot" buttons.
For more information about Memory allocation related details read below articles :
https://medium.com/flutter/flutter-dont-fear-the-garbage-collector-d69b3ff1ca30https://flutter.dev/docs/development/tools/devtools/memory

UPDATED:devtools/memory

ohtdti5x

ohtdti5x2#

您可以从阅读官方文档-https://docs.flutter.dev/development/tools/devtools/memory开始
接下来的步骤描述了如何运行内存视图以及如何手动创建内存泄漏
1.按下“打开Flutter DevTools”按钮。它会打开浏览器。在我的例子中,它是Safari(在Mac上)。如果你只看到一个白色的屏幕,复制链接并粘贴到Chrome。

1.选择“内存”选项卡。

1.按下图表。你会看到所选时间段的很多值。看看“飞镖/Flutter”的内存使用情况。在我的情况下,它是50.52MB

1.您可以使用以下代码模拟大量泄漏:

import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';

 class MemoryLeakObject {
   final String text;

   MemoryLeakObject(this.text);
 }

 List<MemoryLeakObject> leakObjects = [];

 class MemoryLeaksScreen extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Scaffold(
       body: Center(
         child: CupertinoButton(
           child: const Text(
             'Create 1 000 000 leaks',
           ),
           onPressed: () {
             while (leakObjects.length < 1000000) {
               leakObjects.add(
                 MemoryLeakObject('Count: ${leakObjects.length}'),
               );
             }
           },
         ),
       ),
     );
   }
 }

1.使用上述代码打开屏幕,然后按下“创建1 000 000个泄漏”按钮。
1.再看一下这个图。在我的例子中,“Dart/Flutter”内存使用增加到了101.28 MB。同时创建了一个快照,其中包含内存中的所有对象。正如你所看到的,有933365个“MemoryLeakObject”类的对象。

plicqrtu

plicqrtu3#

如果你想/需要添加非集成测试来重现/修复内存泄漏,这里有一种方法。简而言之,它 * 在你的主机上 * 通过简单的flutter test运行,并且完全不依赖于模拟器/真实设备。
示例用法:https://gist.github.com/fzyzcjy/e68c375643d7c77942cdc8fb5f01de18
代码(无示例):

import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'dart:isolate';

import 'package:common_dart/utils/processes.dart';
import 'package:front_log/front_log.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart' hide Isolate, Log;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:vm_service/vm_service_io.dart';

const _kTag = 'vm_services';

// #4657
FutureOr<void> runTestsInVmService(
  FutureOr<void> Function(VmServiceUtil) body, {
  required String selfFilePath,
}) async {
  Log.d(_kTag, 'runInVmService selfFilePath=$selfFilePath Platform.script.path=${Platform.script.path}');

  if (Platform.script.path == selfFilePath) {
    final vmService = await VmServiceUtil.create();
    tearDownAll(vmService.dispose);
    await body(vmService);
  } else {
    test(
      'run all tests in subprocess',
      // #4764
      timeout: const Timeout(Duration(seconds: 60)),
      () async {
        await executeProcess('dart', ['run', '--enable-vm-service', selfFilePath]);
      },
    );
  }
}

/// https://stackoverflow.com/questions/63730179/can-we-force-the-dart-garbage-collector
class VmServiceUtil {
  static const _kTag = 'VmServiceUtil';

  final VmService vmService;

  VmServiceUtil._(this.vmService);

  static Future<VmServiceUtil> create() async {
    final serverUri = (await Service.getInfo()).serverUri;
    if (serverUri == null) {
      throw Exception('Cannot find serverUri for VmService. '
          'Ensure you run like `dart run --enable-vm-service path/to/your/file.dart`');
    }

    final vmService = await vmServiceConnectUri(_toWebSocket(serverUri), log: _Log());
    return VmServiceUtil._(vmService);
  }

  void dispose() {
    vmService.dispose();
  }

  Future<void> gc() async {
    final isolateId = Service.getIsolateID(Isolate.current)!;
    final profile = await vmService.getAllocationProfile(isolateId, gc: true);
    Log.d(_kTag, 'gc triggered (heapUsage=${profile.memoryUsage?.heapUsage})');
  }
}

String _toWebSocket(Uri uri) {
  final pathSegments = [...uri.pathSegments.where((s) => s.isNotEmpty), 'ws'];
  return uri.replace(scheme: 'ws', pathSegments: pathSegments).toString();
}

class _Log extends vm_service.Log {
  @override
  void warning(String message) => Log.w(_kTag, message);

  @override
  void severe(String message) => Log.e(_kTag, message);
}

相关问题