Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in WebMessageChannels #2462

Open
1 of 2 tasks
jdeepwell opened this issue Dec 17, 2024 · 0 comments
Open
1 of 2 tasks

Memory leak in WebMessageChannels #2462

jdeepwell opened this issue Dec 17, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@jdeepwell
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When repeatedly creating and closing WebMessageChannels, the old IOSWebMessageChannel objects do not seem to get fully disposed (even after GC) . Apparently due to a cyclic reference in IOSWebMessageChannel.

Expected Behavior

Old WebMessageChannels with no reference from within the application should be freed.

Steps with code example to reproduce

Steps with code example to reproduce
  bool _createWebMessageChannel(List<dynamic> args) {
    awLogDebug("_createWebMessageChannel");
    void createWebMessageChannel() async {
      javaScriptWebMessageChannel = await _webViewController!.createWebMessageChannel();
      javaScriptPort = javaScriptWebMessageChannel!.port1;
      var port2 = javaScriptWebMessageChannel!.port2;
      javaScriptPort!.setWebMessageCallback(_handleWebMessageChannelMessage);
      awLogDebug("Sending transferAppServiceWorkerPort message to serviceworkerclient");
      _webViewController!.postWebMessage(message: WebMessage(data: "transferAppServiceWorkerPort", ports: [port2]), targetOrigin: WebUri("*"));
    }

    if (Platform.isAndroid) {
      WebViewFeature.isFeatureSupported(WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL).then((isSupported) {
        if (isSupported) {
          createWebMessageChannel();
        }
      });
    }
    else {
      createWebMessageChannel();
    }

    return true;
  }

  void _closeWebMessageChannel() {
    awLogDebug("_closeWebMessageChannel");
    javaScriptWebMessageChannel!.port1.close();
    javaScriptWebMessageChannel!.port2.close();
    javaScriptWebMessageChannel!.dispose();
    javaScriptPort = null;
    javaScriptWebMessageChannel = null;
  }

On each page load a JavaScript hook (via addJavaScriptHandler) is called that re-creates the WebMessageChannel by calling _createWebMessageChannel(). Simply overriding the variable with a new WebMessageChannel should free the old instance (after GC). But even when closing it manually (by calling _closeWebMessageChannel()) the old instances pile up.

Stacktrace/Logs

Stacktrace/Logs
<Replace this line by pasting your stacktrace or logs here>

Flutter version

v3.24.3

Operating System, Device-specific and/or Tool

iOS 17.2

Plugin version

v6.1.5

Additional information

When tracing back to the point where the IOSWebMessageChannel gets created we end up at IOSWebMessageChannel's _fromMap(). In there the generated IOSWebMessageChannel's _iosPort1 and _iosPort1 get associated with that generated IOSWebMessageChannel itself:

    var webMessageChannel = IOSWebMessageChannel(...);
    webMessageChannel._iosPort1.webMessageChannel = webMessageChannel;
    webMessageChannel._iosPort2.webMessageChannel = webMessageChannel;

Thereby those ports hold a reference to the IOSWebMessageChannel and the IOSWebMessageChannel holds references to them.

On each page load we create a WebMessageChannel and store it's reference in a variable (javaScriptWebMessageChannel).

Even if we explicitly close it and set the variables to null via

    javaScriptWebMessageChannel!.port1.close();
    javaScriptWebMessageChannel!.port2.close();
    javaScriptWebMessageChannel!.dispose();
    javaScriptPort = null;
    javaScriptWebMessageChannel = null;

the IOSWebMessageChannel (and port) instances keep going up – see attached screenshot of the Flutter Dev Tools Memory Debugger after re-creating the WebMessageChannel 8 times.

image

Self grab

  • I'm ready to work on this issue!
@jdeepwell jdeepwell added the bug Something isn't working label Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant