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

Websocket memory leak #26660

Closed
sm0kva opened this issue Jun 8, 2016 · 8 comments
Closed

Websocket memory leak #26660

sm0kva opened this issue Jun 8, 2016 · 8 comments

Comments

@sm0kva
Copy link

sm0kva commented Jun 8, 2016

I am getting a memory leak listening on a websocket. The only time I don't leak memory is when I am not creating a parameter to send to the onMessage handler. What I have tried:

ws.onMessage.listen((MessageEvent e) {});

ws.onMessage.listen((MessageEvent e) { e = null});

I attempt to invoke the garbage collector by setting e to null, but I am guessing another reference exists within the Stream.

The issue persists regardless of what I attempt to receive over the socket. It also persists when the websocket's binary type is default or set to arrayBuffer.

Dart version 1.14.2
Dartium version 1.14.2.0

@floitschG
Copy link
Contributor

Do you see this memory leak also in dart2js compiled code?
Do you have similar issues with a more recent version of Dart?

@sm0kva
Copy link
Author

sm0kva commented Jun 8, 2016

Same leak occurs with dart2js compiled code, tested in chrome. I will work on updating Dart to check.

@sm0kva
Copy link
Author

sm0kva commented Jun 8, 2016

Getting the same issue in Dart 1.17.0

@floitschG floitschG added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-io library-html and removed area-dartium library-io labels Jun 8, 2016
@floitschG
Copy link
Contributor

Thanks for testing.
I had a short look at the implementation of WebSocket.onMessage.listen in the dart2js implementation, but the code looks very standard. That is, it uses the usual way of handling JavaScript events, which is used in many other places.
Do you maybe have a repro that we could use?

Note: zones, from dart:async can intercept the callbacks from asynchronous operations (like the one from listening to onMessage). Could you check that you are not running inside any zone? (identical(Zone.current, Zone.ROOT) should return true in the closure that is invoked in the listener).
For example, the stack_trace package uses a zone that keeps track of the stacktraces whenever a program becomes asynchronous. I'm not sure if it has a space limit for them.
If you are using Angular then you are probably also already in a zone. In that case we will need to reduce the repro to code that doesn't use zones first (to exclude them as culprits).

/cc @rakudrama

@sm0kva
Copy link
Author

sm0kva commented Jun 8, 2016

It appears as though I am not running inside of a zone and I am not using Angular. As far as the repro:

  void _openSocket() {
    if (ws == null) {
      ws = new WebSocket('ws://localhost:8080/api/ws/open');
      // ws.binaryType = "arraybuffer";
    }
  }

  void _closeSocket() {
    if (ws != null) {
      ws.close();
      print("socket closed");
      ws = null;
    }
  }

void _openStream (String fieldName, [_]) {
  //Check if we need to open the socket
  _openSocket();
  //Request the proper data
  Map ask = {"Request": "Stream", "Field": fieldName};
  if (ws.readyState == 0){
    ws.onOpen.listen((_) {
      ws.send(JSON.encode(ask));
    });
  } else {
    ws.send(JSON.encode(ask));
  }

  activeQuantities++;
  if (activeQuantities == 1) {
    _listen();
  }
}

// Receive data from the socket
 _listen() {
  ws.onMessage.listen(handlePacket);    
}

void handlePacket(message) {
  message = null;
}

Which manipulates a Websocket member variable to the class running the webpage functionality. I have pretty much isolated the code to opening the websocket and then listening on the websocket. Open stream is invoked when a button on the page is clicked and just signals for more packets to be received.

@jacob314 jacob314 assigned jacob314 and unassigned jacob314 Jun 8, 2016
@jacob314
Copy link
Member

jacob314 commented Jun 8, 2016

Dartium is expected to leak a significant amount of memory and is only intended as a development tool. Dart2js should not leak memory.

@sm0kva
Copy link
Author

sm0kva commented Jun 8, 2016

Just tested with Dart2js again to be sure and still have the leak. The leak seems to be about equal to my packet size coming across the wire if that helps troubleshoot at all.

@sm0kva
Copy link
Author

sm0kva commented Jun 8, 2016

It looks like it is garbage collecting when compiling with Dart2js, it just allows the memory to climb ~500MB before it collects. I wasn't hitting that threshold with my original streaming rate so it looked like the same leak that would make Dartium run up to ~1.3GB and then crash.

Thank you guys for the help.

@floitschG floitschG added area-dartium and removed area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-html labels Jun 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants