Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 创建垃圾的Web工作者_Javascript_Garbage Collection_Garbage - Fatal编程技术网

Javascript 创建垃圾的Web工作者

Javascript 创建垃圾的Web工作者,javascript,garbage-collection,garbage,Javascript,Garbage Collection,Garbage,我正在做一个利用网络工作者的项目。工人们似乎正在产生相当多的额外垃圾,这些垃圾必须从消息传递中收集 我从主线程通过post消息将三件事发送给工人。第一个只是一个数字,第二个是一个包含7个数字的数组,第三个是日期。前两个是对象的属性,如下所示。对于大约20个对象,在RAF上每16毫秒调用一次。GC最终每隔2秒左右收集12MB数据。我想知道是否有一种方法可以做到这一点而不产生这么多垃圾?谢谢你的帮助 //planet num (property of object) is just

我正在做一个利用网络工作者的项目。工人们似乎正在产生相当多的额外垃圾,这些垃圾必须从消息传递中收集

我从主线程通过post消息将三件事发送给工人。第一个只是一个数字,第二个是一个包含7个数字的数组,第三个是日期。前两个是对象的属性,如下所示。对于大约20个对象,在RAF上每16毫秒调用一次。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}});

我尝试了两种不同的方法,最后使用了它们的组合。首先,在我发送一些元素之前,我使用JSON.stringify将它们转换为字符串,然后使用JSON.parse将它们发送给worker后返回。对于数组,我最终使用了可转移对象。以下是我所做工作的简化示例:

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]);
这会将数组发送给工作进程,而不会复制它,从而减少产生的垃圾。它现在在主线程中不可访问,因此一旦工作线程发布消息,您必须将数组发送回主线程,否则它将不再作为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
}

目前还不确定这是否是最好的方法,但它确实可以在不产生一堆额外垃圾的情况下将数组发送到工作线程。我认为这里最好的方法是将数组发送给worker并将其留在那里,然后返回更新的位置。在那台蒸馏器上工作。

有多少工人?有多少不同的行星被操纵?这似乎是一个很有希望的开始:我有两个工人,一个负责9颗行星,然后更多的小行星以同样的方式处理另一颗。现在我只是想弄清楚如何用一个工人把垃圾倒下来。那篇文章读得很好,我一定会试试看。不过,它似乎不会减少复制过程中产生的垃圾。我认为arraybuffer可能会有所帮助,但我不确定是否可以将其用于对象属性?如果您想要零分配消息,则需要
SharedArrayBuffer
。如果需要低分配开销,则需要将数组缓冲区传递为可传递的参数,并在它们被发送回来时循环使用它们。无论如何,6Mb/s如果您认为每秒有60帧,并且消息传递可能涉及内部严格化,则不是那么多。因此,即使一切都是最优的,您仍然会期望几十KB/s