Sim*_*Frr 7 javascript garbage-collection v8 real-time google-chrome-devtools
所以我正在研究这个相当复杂的实时应用程序.我有一个音频引擎,每100毫秒触发重音频处理功能,以填充立即播放的缓冲区.如果这些音频功能运行得太晚,甚至一次,你可以听到声音口吃.
大多数时候一切都很好.然而,当垃圾收集器由V8触发时,完成一个圆形需要大约150ms,这会触发上述裂缝.
所以这里有一个问题:我怎样才能获得更短的垃圾收集?
几点评论:
我们可以尝试分配更少的变量,以便堆增长得更慢,但我想这不会解决问题:即使GC被频繁触发一半,我也没有看到任何理由为什么集合应该运行得更快.我宁愿让它经常运行两次,也只是运行一半.
我已经阅读了一些关于V8 GC的内容.我知道我无法直接控制GC.我知道它有一个短期过程和一个长期过程(标记和扫描).我想这是导致问题的后者.但是,我不知道它花费这么长时间的确切原因:是删除的数据量还是浏览的数据结构?知道这一点可能会有所帮助.
我已经尝试过广泛使用Chrome Dev Tools,根据 这篇文章,我需要使用"Record Heap Allocations"模块.但是当我运行并同时查看时间轴时,我可以看到它一直触发垃圾收集,就像堆快照一样,所以我无法真正追踪到什么使我的内存增长.
我们没有任何内存泄漏,这已经过测试.没有常规的DOM访问,也没有创建事件侦听器.我想这是一个常见的问题,考虑到具有高FPS的应用程序的数量......请帮忙!
编辑
我们想到的另一种解决方案是将数据存储在内存泄漏中,以便在我们明确决定释放内存之前GC不会运行.这听起来像一个邪恶的黑客,有没有人这样做过?你怎么看?
您可以尝试实现“对象池”设计模式。基本原则是重用变量而不是创建和删除变量。最好按对象类型拥有一个池。
这是一个非常基本的实现。
var pool = [];
var poolRelease = function(obj) {
pool.push(obj);
};
var poolGet = function() {
// You could add parameters to the function to directly set the values of the object.
if (pool.length) {
return pool.pop();
}
// We don't have preexisting object, create it (can be anything).
return {x: 0, y: 0};
}
// Then in the code:
var myObj = poolGet();
myObj.x = 20;
// When finished with the object move it back to the pool to avoid garbage collection.
poolRelease(myObj);
Run Code Online (Sandbox Code Playgroud)