JavaScript传递对象给函数时的内存分配

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

Javascript memory allocation while passing objects to functions

问题

最近,我的应用程序中出现了长时间的小型和大型垃圾回收扫描的问题,总体上我分配了太多内存太快。但这也让我考虑了一个情况:通常当一个函数有多个参数时,我会创建一个对象,以避免混淆顺序,我在想这样做会对小型和大型垃圾回收扫描产生多大影响。考虑两种情况:

  1. const fn = (arg1, arg2, arg3, arg4) => {...}
  2. const fn = ({ arg1, arg2, arg3, arg4 }) => {...}

微妙的变化,但在第一个示例中,我们不分配任何内存,对吗?所有变量已经定义并分配了内存。在第二个示例中,如果我们想调用这个函数,我们必须创建对象,因此需要分配内存。

因此,我想知道如果我非常快速地调用第二个函数,比如每几毫秒一次,是否会使垃圾回收扫描时间变得更长,或者它可以忽略不计?它是否分配内存,还是JavaScript引擎会处理这个,就像第一个示例中一样,基本上是免费的?

英文:

recently I had problem with long minor and major gc sweeps in my app, overall I was allocating too much memory too quickly. But it also got me thinking on such case: Often when there are multiple arguments to function I'm creating an object to not mess up order and I'm wondering how much does it affect minor and major gc sweeps. Consider 2 scenarios:

  1. const fn = (arg1, arg2, arg3, arg4) => {...}
  2. const fn = ({ arg1, arg2, arg3, arg4 }) => {...}

Subtle change, but in first example we are not allocating any memory right? All of the variables are already defined and have memory allocated for them. In the second example if we want to call this function, we have to create object therefore allocate memory.

So I was wondering if I'm calling 2nd function very quickly, like every few ms, is it making garbage collector sweeps a lot longer, or maybe it's negligible? Does it even allocate memory or JS engines are taking care of that and it's basically free as in 1st example?

答案1

得分: 0

in first example we are not allocating any memory right?
第一个示例中我们没有分配任何内存,对吗?

if I'm calling 2nd function very quickly, like every few ms, is it making garbage collector sweeps a lot longer, or maybe it's negligible?
如果我非常快地调用第二个函数,比如每隔几毫秒,会使垃圾收集器的清理时间变得更长,还是可以忽略不计?

Should be negligible: an object every few milliseconds is no problem for the garbage collector. In particular, these objects should be very short-lived (unless you're storing references to them somewhere), so they should never make it to the old generation, and hence won't affect major GC cycles.
应该可以忽略不计:每隔几毫秒创建一个对象对于垃圾收集器来说不是问题。特别是这些对象应该寿命很短(除非你在某个地方存储了对它们的引用),因此它们不应该进入老代,因此不会影响主要的GC周期。

If you wanted to execute this call hundreds of times per millisecond, there might be more reason to have performance concerns, but see the point below.
如果你想每毫秒执行这个调用数百次,那可能会有更多性能方面的考虑,但请参见下面的观点。

Does it even allocate memory or JS engines are taking care of that and it's basically free as in 1st example?
它甚至会分配内存吗,还是JS引擎会处理这个,就像第一个示例中一样基本上是免费的?

Depends.
这取决于。
Generally speaking, you're creating an object there, and that's an allocation.
一般来说,你在这里创建了一个对象,这就是一次分配操作。
However, if that call is very hot, then the calling function will get optimized eventually, and the callee might get inlined, and after inlining the parameters object might get optimized out (by a technique often called "escape analysis" in the optimizing compiler). In that case, the result will be as efficient as the first example.
然而,如果这个调用非常频繁,那么调用函数最终会被优化,被调用的函数可能会被内联,然后在内联后,参数对象可能会被优化掉(通过通常被称为"逃逸分析"的技术在优化编译器中)。在这种情况下,结果将与第一个示例一样高效。

英文:

(V8 developer here.)

> in first example we are not allocating any memory right?

Right.

> if I'm calling 2nd function very quickly, like every few ms, is it making garbage collector sweeps a lot longer, or maybe it's negligible?

Should be negligible: an object every few milliseconds is no problem for the garbage collector. In particular, these objects should be very short-lived (unless you're storing references to them somewhere), so they should never make it to the old generation, and hence won't affect major GC cycles.

If you wanted to execute this call hundreds of times per millisecond, there might be more reason to have performance concerns, but see the point below.

> Does it even allocate memory or JS engines are taking care of that and it's basically free as in 1st example?

Depends.
Generally speaking, you're creating an object there, and that's an allocation.
However, if that call is very hot, then the calling function will get optimized eventually, and the callee might get inlined, and after inlining the parameters object might get optimized out (by a technique often called "escape analysis" in the optimizing compiler). In that case, the result will be as efficient as the first example.

huangapple
  • 本文由 发表于 2023年3月15日 18:58:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743788.html
匿名

发表评论

匿名网友

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

确定