Repository: flutter
Issue: Invisible IOSurfaces with multiple engines are not deallocated
Labels: platform-ios,engine,d: examples,a: existing-apps,perf: memory,P2,team-ios,triaged-ios

Bug report from comment: https://github.com/flutter/flutter/issues/72009#issuecomment-792516067
cc @iLees

**doctor**:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.0, on macOS 11.2.2 20D80 darwin-x64, locale
    zh-Hans-CN)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for
      more details.
[!] Xcode - develop for iOS and macOS
    ! CocoaPods 1.9.0 out of date (1.10.0 is recommended).
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin
        code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To upgrade see
      https://guides.cocoapods.org/using/getting-started.html#installation for
      instructions.
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] Connected device (3 available)

! Doctor found issues in 2 categories.

**code**：
```swift
class AppDelegate: UIResponder, UIApplicationDelegate {
    let engines = FlutterEngineGroup(name: "multiple-flutters", project: nil)
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    #if DEBUG
      let isDebug = true
    #else
      let isDebug = false
    #endif
    if isDebug {
      NSLog(
        "📣 NOTICE: the memory and CPU costs for Flutter engine groups are significantly greater in debug builds.  See also: https://github.com/dart-lang/sdk/issues/36097"
      )
    } else {
      NSLog(
        "📣 NOTICE: the memory and CPU costs for Flutter engine groups are significantly less here than in debug builds.  See also: https://github.com/dart-lang/sdk/issues/36097"
      )
    }
    return true
  }
}

class HostViewController: UIViewController, DataModelObserver {
  @IBOutlet weak var countView: UILabel!
    let appdelegate = UIApplication.shared.delegate as? AppDelegate
  deinit {
    UIApplication.shared.keyWindow?.backgroundColor = UIColor.white;
  }

  func onCountUpdate(newCount: Int64) {
    self.countView.text = String(format: "111111%d", newCount)
  }

  @IBAction func onAddCount() {
    DataModel.shared.count = DataModel.shared.count + 1
  }

  @IBAction func onNext() {
    let navController = self.navigationController!
    let vc = SingleFlutterViewController(withEntrypoint: nil)
    navController.pushViewController(vc, animated: true)
  } 
}

class SingleFlutterViewController: FlutterViewController, DataModelObserver {
  private var channel: FlutterMethodChannel?

  init(withEntrypoint entryPoint: String?) {
    let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
    let newEngine = appDelegate.engines.makeEngine(withEntrypoint: entryPoint, libraryURI: nil)
    super.init(engine: newEngine, nibName: nil, bundle: nil)
  }

  required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  func onCountUpdate(newCount: Int64) {
    if let channel = channel {
      channel.invokeMethod("setCount", arguments: newCount)
    }
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    channel = FlutterMethodChannel(
      name: "multiple-flutters", binaryMessenger: self.engine!.binaryMessenger)
    channel!.invokeMethod("setCount", arguments: DataModel.shared.count)
    let navController = self.navigationController!
    channel!.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
      if call.method == "incrementCount" {
        DataModel.shared.count = DataModel.shared.count + 1
        result(nil)
      } else if call.method == "next" {
        let vc = SingleFlutterViewController(withEntrypoint: nil)
        navController.pushViewController(vc, animated: true)
      } else {
        result(FlutterMethodNotImplemented)
      }
    }
  }
}

```

**Xcode run profile :**
![8EAD48A3D8A1D1392ED2BE8F7E680CBB](https://user-images.githubusercontent.com/13429343/110284122-416c7a80-801c-11eb-8ad6-70524f863d5d.jpg)

<img width="1294" alt="截屏2021-03-08 下午2 35 05" src="https://user-images.githubusercontent.com/13429343/110284289-885a7000-801c-11eb-89f6-f616de9cc2f0.png">

click the next button：
![8A9213D7C8ACB32C75979315A6CCE1BE](https://user-images.githubusercontent.com/13429343/110284371-acb64c80-801c-11eb-8983-74e17adfe342.jpg)

Persistent Memory ：2.36MB

<img width="1287" alt="截屏2021-03-08 下午2 35 42" src="https://user-images.githubusercontent.com/13429343/110284380-b17b0080-801c-11eb-9012-5751a915f3d9.png">

Persistent Memory ：45.35MB

click the next button of the flutter page：
<img width="1286" alt="截屏2021-03-08 下午2 35 57" src="https://user-images.githubusercontent.com/13429343/110284525-e8511680-801c-11eb-89cd-87be33400b4a.png">

Persistent Memory ：88.51MB