【问题标题】:How to clear closed RTCPeerConnection >> [with WORKAROUND]如何清除关闭的 RTCPeerConnection >> [with WORKAROUND]
【发布时间】:2021-06-07 08:16:11
【问题描述】:

这是著名的 Chromium 旧 bug:https://bugs.chromium.org/p/chromium/issues/detail?id=825576

错误是:Failed to construct 'RTCPeerConnection': Cannot create so many PeerConnections

现在因为 Edge 是基于 Chromium 的,所以不仅 Chrome 会受到这个错误的影响,这让事情变得更糟。

我们需要找到一种方法来强制垃圾收集器循环。

我发布了我当前的解决方法,但我很高兴找到更好的解决方法,如果有的话...?

【问题讨论】:

    标签: javascript google-chrome webrtc microsoft-edge chromium


    【解决方案1】:

    经过一段时间的尝试,我发现强制/调用垃圾收集器的最佳解决方法是创建然后撤销一些数据缓冲区。

    Chrome/Edge 上最简单的修复方法是使用:

    URL.revokeObjectURL(URL.createObjectURL(new Blob([new ArrayBuffer(5e+7)]))) // 50Mo buffer
    

    但是 那么,这会在 Firefox 上引入内存泄漏。 在 Firefox 上,似乎 ObjectURL 不能在不绑定到 DOM 元素的情况下被撤销。在spec 中找不到任何相关信息。

    所以跨浏览器解决方案(Chrome/Edge/Firefox,其他浏览器未测试),将是:

    queueMicrotask(() => { // || >> requestIdleCallback
      let img = document.createElement("img");
      img.src = window.URL.createObjectURL(new Blob([new ArrayBuffer(5e+7)])); // 50Mo
      img.onerror = function() {
        window.URL.revokeObjectURL(this.src);
        img = null
      }
    })
    

    这是修复 WebRTC 错误的示例工作代码:

    var i = 1;
    
    function peer() {
      var peer = new RTCPeerConnection();
      setTimeout(() => {
        peer.close();
        peer = null;
      }, 10);
      console.log(i++);
      if (!(i % 20)) {
        // try to invoke GC on each 20ish iteration
        queueMicrotask(() => { 
          let img = document.createElement("img");
          img.src = window.URL.createObjectURL(new Blob([new ArrayBuffer(5e+7)])); // 50Mo or less or more depending as you wish to force/invoke GC cycle run
          img.onerror = function() {
            window.URL.revokeObjectURL(this.src);
            img = null
          }
        })
      }
    }
    
    setInterval(peer, 20);

    【讨论】:

    • 你能补充一下(很糟糕,但如果它有效的话......)解决 chrome 问题的方法吗?
    【解决方案2】:

    如果您可以控制 chromium 进程,您实际上可以将垃圾收集器暴露给 javascript。请参阅此答案 https://stackoverflow.com/a/13951759/1563399 的编辑。

    编辑声明您可以将--js-flags="--expose-gc" 添加到您的启动标志中。然后它将公开一个名为 gc 的全局函数,可以调用该函数来调用垃圾收集器。

    我尝试使用解决方案A. Wolff posted here。但这似乎会导致我的嵌入式树莓派项目出现内存泄漏。

    【讨论】:

      猜你喜欢
      • 2017-10-03
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      相关资源
      最近更新 更多