我正在开发一个利用网络工作者的项目。似乎工人正在产生相当多的额外垃圾,必须从传递的消息中收集。
我通过主线程的帖子消息向工作人员发送三件事。第一个是数字,第二个是7个数字的数组,第3个是日期。第一个是物体的属性,如下所示。对于大约20个对象,这在RAF上每16ms调用一次。 GC最终每2秒左右收集12MB。我想知道是否有办法在不创造这么多垃圾的情况下做到这一点?谢谢你的帮助!
//planet num (property of object) is just a number like: 1
//planetele looks like this (property of an object)
//[19.22942, 313.4868, 0.04441, 0.7726, 170.5310, 73.9893, 84.3234]
//date is just the date object
//posted to worker like so:
planetWorker.postMessage({
"planetnum": planet.num,
"planetele": planet.ele,
"date": datet
});
//the worker.js file uses that information to do calculations
//and sends back the planet number, with xyz coordinates. (4 numbers)
postMessage({data: {planetnum : planetnum, planetpos: planetpos}});
答案 0 :(得分:2)
我尝试了两种不同的途径,最后结合使用它们。首先,在我发送一些元素之前,我使用JSON.stringify将它们转换为字符串,然后JSON.parse将它们发送给工作者后将其恢复。对于数组,我最终使用了可转移对象。以下是我所做的简化示例:
var ast = [];
ast.elements = new Float64Array([0.3871, 252.2507, 0.20563, 7.005, 77.4548, 48.3305, 0.2408]);
ast.num = 1;
var astnumJ = JSON.stringify(ast.num); // Probably not needed, just example
// From main thread, post message to worker
asteroidWorker.postMessage({
"asteroidnum": astnumJ,
"asteroidele": ast.elements.buffer
},[ast.elements.buffer]);
这会将数组发送给worker,它不会复制它,这样可以减少所产生的垃圾。它现在无法在主线程中访问,因此一旦工作者发布消息,您必须将数组发送回主线程,否则它将不再作为ast的属性访问。在我的情况下,因为我有20 - 30个ast对象,我需要确保它们都通过post消息恢复它们的元素,然后再调用它们。我在一个循环中用一个简单的计数器做到了这一点。
// In worker.js
asteroidele = new Float64Array(e.data.asteroidele); // cast to type
asteroidnum = JSON.parse(e.data.asteroidnum); // parse JSON
// Do calculations with this information in worker then return it to the main thread
// Post message from worker back to main
self.postMessage({
asteroidnum : asteroidnum,
asteroidpos : asteroidpos, // Calculated position with elements
asteroidele : asteroidele // Return the elements buffer back to main
});
// Main thread worker onmessage function
asteroidWorker.onmessage = function(e){
var data1 = e.data;
ast.ele = data1.asteroidele; // Restore elements back to ast object
}
不确定这是最好的方法,但它确实可以在不产生大量额外垃圾的情况下向工作人员发送数组。我认为这里最好的方法是将数组发送给工作者并将其保留在那里,然后返回更新的位置。继续努力。