未挂载到DOM的video元素何时被垃圾回收?含暂停场景疑问
未挂载DOM的Video元素垃圾回收问题解答
先来看这段创建未挂载DOM的video元素并播放的代码:
async function createVideo() { const videoEl = document.createElement("video"); videoEl.autoplay = true; videoEl.src = "https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4"; await videoEl.play() return videoEl } createVideo() .then(() => console.log('video is playing')) .catch(error => console.log(error))
在Chrome中该视频能正常播放,但元素并未挂载到DOM,针对这一场景的两个疑问,我来逐一解答:
1. 该video元素会在何时被垃圾回收(garbage collected)?
垃圾回收的核心判断标准是这个元素是否还存在任何可访问的引用,具体到这个场景:
- 如果调用
createVideo()后,没有把返回的videoEl赋值给任何变量(就像当前代码里这样,then回调只是打印日志,没保留引用),那么只要视频播放停止(包括播放完毕、主动暂停、播放出错等情况),浏览器的垃圾回收器就会在合适的回收周期里把它标记为可回收对象,进而释放它占用的内存。 - 但要注意:只要视频处于正在播放的状态,浏览器会因为该元素关联着活跃的媒体播放上下文,自动保留对它的引用,此时垃圾回收器不会回收它——毕竟媒体资源还在被使用呢。
2. 若在createVideo()函数内返回video元素前执行video.pause(),垃圾回收机制会如何运作?该元素会永久成为僵尸对象吗?
完全不会变成永久僵尸对象,垃圾回收器会正常处理它:
- 当你在返回前执行
videoEl.pause(),首先会终止媒体播放,此时这个video元素不再持有任何活跃的媒体资源,也没有浏览器内部的强制引用了。 - 函数执行完成后,如果没有外部变量持有这个元素的引用,那么V8引擎(Chrome的JS引擎)的标记清除算法会在下一次垃圾回收时,识别出这个元素已经没有任何可达引用,从而将它回收,释放内存。
- 所谓“僵尸对象”是指存在无效引用却无法被回收的情况,但这里只要没有任何代码还能访问到这个video元素,就不会出现这种问题,浏览器的垃圾回收机制完全能处理干净。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

