JavaScript垃圾收集器何时删除由闭包关系覆盖的变量?

huangapple go评论65阅读模式
英文:

When will Javascript garbage collector delete variables that are covered by closure relations?

问题

I'm receiving chunks of data asynchronrously via SSE and it is slowly but surely populating a dictionary {UPD.x, UPD.y}, whose contents I want to display with ploty.js. I want to see the graph steadily update as more chunks arrive.

我通过SSE异步接收到数据块,它正在逐渐填充一个字典{UPD.x, UPD.y},我想使用plotly.js显示其内容。我希望随着更多数据块的到达,图表稳定更新。

I do the plotly calls similar to this

我做的Plotly调用类似于这样:

eventSource.onmessage = function(event) {
const data = json.parse(event.data);
const UPD = data.upd;
Plotly.update (PLOTTER, UPD, [0]);
}

where PLOTTER is global in the calling program. My thought is that while UPD is local to that function, the update command copies the reference as PLOTTER.data = UPD and so UPD should survive any garbage collection as long as PLOTTER stays alive at least until the next batch of data arrives, when the old UPD would get garbage collected.

其中PLOTTER在调用程序中是全局的。我的想法是,虽然UPD是该函数的局部变量,但更新命令会将引用复制为PLOTTER.data = UPD,因此只要PLOTTER至少存活到下一批数据到达之前,UPD应该不会被垃圾回收。

A) Do I have that correct?

A) 我说得对吗?

B) Taking this one step further, I really just want to be sure to display the last graph, I don't really care if I "miss" some plots of partial data. If new data has arrived since the last promise to Plotly.update() was issued then I'd really just want to blow off that earlier call. I think a solution to that could be to make UPD itself global to the function. What are the potential downfalls to that? Worst case that I can see is that it could result in a few extra calls to Plotly.update if the data arrives ahead of the plot. But maybe there could be an obscure race condition if UPD updates in the middle of a plot...

B) 进一步说,我真的只想确保显示最后的图表,如果我“错过”了一些部分数据的绘图,我并不真的在意。如果自上次调用Plotly.update()的承诺以来有新数据到达,那么我真的只想忽略掉之前的调用。我认为解决方法可能是将UPD本身设置为函数的全局变量。这样做的潜在问题是什么?我能想到的最糟糕情况是,如果数据在绘图之前到达,可能会导致多次调用Plotly.update。但如果UPD在绘图过程中更新,可能会出现一些不明显的竞争条件...

英文:

I'm receiving chunks of data asynchronrously via SSE and it is slowly but surely populating a dictionary {UPD.x, UPD.y}, whose contents I want to display with ploty.js. I want to see the graph steadily update as more chunks arrive.

I do the plotly calls similar to this

eventSource.onmessage = function(event) { 
   const data = json.parse(event.data);
   const UPD = data.upd;
   Plotly.update (PLOTTER, UPD, [0]);
}

where PLOTTER is global in the calling program. My thought is that while UPD is local to that function, the update command copies the reference as PLOTTER.data = UPD and so UPD should survive any garbage collection as long as PLOTTER stays alive at least until the next batch of data arrives, when the old UPD would get garbage collected.

A) Do I have that correct?

B) Taking this one step further, I really just want to be sure to display the last graph, I don't really care if I "miss" some plots of partial data. If new data has arrived since the last promise to Plotly.update() was issued then I'd really just want to blow off that earlier call. I think a solution to that could be to make UPD itself global to the function. What are the potential downfalls to that? Worst case that I can see is that it could result in a few extra calls to Plotly.update if the data arrives ahead of the plot. But maybe there could be an obscure race condition if UPD updates in the middle of a plot...

答案1

得分: 1

The update command copies the reference as "PLOTTER.data = UPD," so UPD should survive any garbage collection as long as PLOTTER stays alive. Do I have that correct?
No, 你真的需要区分UPD 变量 和由 data.upd, UPDPLOTTER.data 引用的 对象

UPD 变量本身将在 onmessage 函数结束时被垃圾回收,就像 eventdata 变量一样。这将从 UPD 到该对象的引用中删除一个引用,由于 data 对象不再被引用,从其 .upd 属性到该对象的引用也将被删除。

然而,之前多次引用的对象仍然从 PLOTTER 对象的 .data 属性中引用,由于这似乎是一个全局变量(或至少是由 eventSource 监听器封闭的变量),它将不会被垃圾回收。

英文:

> the update command copies the reference as PLOTTER.data = UPD and so UPD should survive any garbage collection as long as PLOTTER stays alive. Do I have that correct?

No, you really need to distinguish between the UPD variable and the object that is referenced by data.upd, UPD and PLOTTER.data.

The UPD variable itself will get garbage-collected as soon as the onmessage function ends, just like the event and data variables. This will remove one reference from UPD to the object, and since the data object is no longer referenced, another reference from its .upd property to the object.

The object that was previously referenced multiple times is however still referenced from the .data property of the PLOTTER object, and as that seems to be a global variable (or at least a variable closed over by the eventSource listener), it will not be garbage-collected.

huangapple
  • 本文由 发表于 2023年4月20日 05:57:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76059105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定