javascript - Web Worker 制造垃圾

标签 javascript garbage-collection garbage

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

我正在通过主线程的 post 消息向工作人员发送三样东西。第一个只是一个数字,第二个是一个有 7 个数字的数组,第三个是日期。前两个是对象的属性,如下所示。这在 RAF 上每 16 毫秒调用一次,用于大约 20 个对象。 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 在将它们发送给工作人员后将它们取回。对于数组,我最终使用了可转移对象。这是我所做的一个简化示例:

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 对象,我需要确保在调用另一个更新之前它们都通过发布消息恢复了它们的元素。我在循环中使用一个简单的计数器来完成此操作。

// 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 或从 worker 接收到数组。我认为这里最好的方法是将数组发送给工作人员并将其留在那里,然后只返回更新后的位置。仍在努力。

关于javascript - Web Worker 制造垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42753869/

相关文章:

javascript - 使用 CanvasRenderer 在 three.js 中绘制线条比 WebGLRenderer 绘制的线条更平滑

javascript - 为什么我的 Google 分析漏斗显示 0,但目标显示很高的数字?

java - 垃圾收集最小化。有人会澄清一些关于迭代器的事情吗?

c++ - std::map 初始化(仅一次)

c++ - getline 的垃圾值

c# - ASPxCombobox,允许用户输入和下拉选择

javascript - 如何到达内联 javascript 回调函数的父作用域?

java - JVM 使用 JOGL、顶点缓冲区对象并尝试在 finalize 方法中释放 vbo 时崩溃

c# - 使用 Dispose() 从 Form 中删除 Control

java - 避免在 Java 中创建 Iterator 实例