DART是否对先前使用的实例重用内存?

发布于 2025-02-12 20:21:05 字数 573 浏览 3 评论 0原文

很难为此找到一个好的标题,但是我认为如果我发布了一个小密码,我的问题很清楚:

SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM

instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM

我的问题现在是,在第二次施工中第一次施工中分配了二手的RAM吗?还是第一个实例的RAM标记为垃圾收集器未使用,第二个结构是用带有不同部分的RAM的全新实例完成的?

如果第一个是正确的,那么这是什么:

while(true) {
    final SomeObject instance = SomeObject(importantParameter);
}

然后,每次重复时,RAM都会重复使用?

It is hard to find a good heading for this, but i think my problem comes clear if i post a small code snipped:

SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM

instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM

My question is now, is the used RAM that was allocated at the first construction reused at the second construction? Or is the RAM of the first instance marked as unused for the garbage collector and the second construction is done with a completely new instance with a different portion of RAM?

If the first is true, what with this:

while(true) {
    final SomeObject instance = SomeObject(importantParameter);
}

Will then, each time the while is repeated, the RAM be reused?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月下凄凉 2025-02-19 20:21:05

它未指定。答案是一个响亮的“也许”。

语言规范从未说出无法到达的对象会发生什么,因为该程序对程序无法观察。 (这就是无法达到的意思)。

实际上,本地DART实施使用了世代相传的垃圾收集器。
默认行为将是在“新空间”中分配一个新对象,并覆盖对先前对象的引用。这使得以前的对象无法到达(只要您没有存储其他引用),因此可以收集垃圾。如果您真的很快地浏览对象,那将是便宜的,因为在下一个新空间垃圾收集中完全忽略了无法到达的对象。
分配大量的短寿命对象仍然有一个开销,因为它会导致新空间GC更频繁地发生,即使单个对象本身不花任何费用。

还有许多优化可能会改变这种行为。
如果您的对象非常简单,并且编译器可以看到对其对象没有引用,或者在相同的检查或...其他数量的相关限制中使用,则可能“分配”下沉“对象。这意味着它从来没有真正分配对象,它只是将内容存储在某个地方,甚至可以在堆栈中存储,并且还嵌入了方法,因此它们直接参考数据,而不是浏览this指针。

在这种情况下,您的代码实际上可以重复使用上一个对象的内存,因为编译器认识到它可以。

不要试图预测这种优化是否发生。要求随时可以改变。只需编写正确的代码,而不是不必要的复杂,那么编译器就会尽最大努力以其所有方式优化。

It's unspecified. The answer is a resounding "maybe".

The language specification never says what happens to unreachable objects, since it's unobservable to the program. (That's what being unreachable means).

In practice, the native Dart implementation uses a generational garbage collector.
The default behavior would be to allocate a new object in "new-space" and overwrite the reference to the previous object. That makes the previous object unreachable (as long as you haven't store other references to it), and it can therefore be garbage collected. If you really go through objects quickly, that will be cheap, since the unreachable object is completely ignored on the next new-space garbage collection.
Allocating a lot of short-lived objects still has an overhead since it causes new-space GC to happen more often, even if the individual objects don't themselves cost anything.

There is also a number of optimization that may change this behavior.
If your object is sufficiently simple and the compiler can see that no reference to it ever escapes, or is used in an identical check, or ... any other number of relevant restrictions, then it might "allocation sink" the object. That means it never actually allocates the object, it just stores the contents somewhere, perhaps even on the stack, and it also inlines the methods so they refer to the data directly instead of going through a this pointer.

In that case, your code may actually reuse the memory of the previous object, because the compiler recognizes that it can.

Do not try to predict whether an optimization like this happens. The requirements can change at any time. Just write code that is correct and not unnecessarily complex, then the compiler will do its best to optimize in all the ways that it can.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文