当前位置: 首页 > 知识库问答 >
问题:

这是真的吗-垃圾收集器不会收集结构类型的对象

卢元龙
2023-03-14

昨天,我们讨论了垃圾收集。

有人讨论过,使用类创建的对象由垃圾收集器收集,但如果是使用struct创建的,则不能由GC收集

我知道结构使用堆栈,类使用堆。

但是,我猜GC永远不会只收集非托管代码。这是否意味着结构类型是非托管代码。(我不这么认为)。

还是GC只负责堆而不负责堆栈?

如果是,那么int数据类型呢。int是struct而不是class。那么,如果我们定义int类型的对象,它不是由GC管理吗?

共有3个答案

徐瀚
2023-03-14

但是,我想GC永远不会只收集非托管代码。所以这意味着结构类型是非托管代码。(我不这么认为)。

我不明白你在问什么。

或者这意味着GC只负责堆而不是堆栈?

是和否。GC负责引用类型实例(总是在托管堆上创建)所需的内存。您可以将“堆栈”视为与当前执行线程关联的一段内存。堆栈可以包含对托管堆上分配的引用类型的句柄。在这种情况下,GC“关心”:在堆栈上存在这些引用之前,它不会从这些实例的托管堆中收集内存。堆栈还可以包含实例(不引用!)值类型,在这种情况下GC不关心。。。

如果是,那么int数据类型呢。int是struct而不是class。那么,如果我们定义int类型的对象,它不是由GC管理吗?

这个问题有点误导。假设你在堆栈上“分配”了一个int的实例:

void Foo()
{
    // ...
    int tTmp;
    //...
}

在这种情况下,GC不关心tTmp。如果超出范围,它将被放置在当前线程的堆栈上并移除。但如果你这么做:

void Foo()
{
    //...
    var tTmp = new int [] {
        1, 2, 3, 4
    };
    //...
}

然后在托管堆上创建4个整数的数组,GC负责tTmp。它还“间接”处理数组内容所需的内存,这恰好是四个整数所需的空间。。。

单品
2023-03-14

如果它是使用struct创建的,则GC无法收集它。

不是真的。如果没有被引用,最终将被收集。

我知道结构使用堆栈,类使用堆。

这是一个常见的误解。详细信息请参阅Lippert的文章。

我认为您提到的想法是,GC通常不需要收集位于堆栈上的任何数据,因为一旦程序执行离开其作用域,堆栈就会被销毁。因此,这意味着直接放入堆栈的任何数据(可能意味着值类型,应该意味着对所有其他数据的引用)都将被自动清除,无需使用GC。GC的工作是独立于堆数据的(数据)类型清除堆数据。如果它没有被引用,它就会被收集。

薛经纶
2023-03-14

如果无法从GC根访问任何托管对象(结构是托管对象),GC将收集这些对象。

但如果它是使用struct创建的,则GC无法收集它。

你被告知的是不正确的。托管对象是如何创建的并不重要——如果不再有对它的引用,它最终会被收集。

或者这意味着GC只负责堆而不是堆栈?

GC负责对象图——如果任何GC根都可以访问对象,则不会收集它们,如果不可以,则最终会被收集。堆栈和堆不相关。

因此,如果我们定义int类型的对象,它不是由GC管理吗?

int(又称System.Int32)是一个托管对象——一种结构。例如,如果在类中声明一个int字段,并且该类超出了范围,那么int最终将由GC收集。

正如@leppie评论的那样,在许多情况下,结构将被放置在堆栈上,当堆栈被弹出时,它们将不再存在——在这种情况下,GC不参与(也不需要参与)。

 类似资料:
  • 来自MSDN:“当一个对象不可访问时,垃圾收集器会将该对象视为垃圾。然后,当垃圾收集器将一个对象的条目从终结队列移动到freachable队列时,该对象不再被视为垃圾,其内存也不会被回收。此时,垃圾收集器已完成对垃圾的识别。一些被识别为垃圾的对象已被重新分类。”被归类为非垃圾。垃圾收集器压缩可回收内存,特殊运行时线程清空可回收队列,执行每个对象的Finalize方法。需要两个GC来回收需要终结的对

  • 问题内容: 我从带有node.js的线程垃圾收集中学到了node.js使用世代GC。 我通常使用循环对象引用(最终我都会删除/确保超出范围),并想知道node.js是否能很好地处理它们。所以例如。如果使用参考完成。计数,会有一个问题,所以我想知道这个节点有多好。 一些使用场景: 对于每个http请求,我创建一个带有lambda的setTimeout,该lambda可能引用了范围对象。作用域对象还引

  • Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner

  • Java 15 使 ZGC、Z 垃圾收集器成为标准功能。它是 Java 15 之前的一个实验性功能。它是低延迟、高度可扩展的垃圾收集器。 ZGC 是在 Java 11 中作为一项实验性功能引入的,因为开发人员社区认为它太大而无法提前发布。 即使在机器学习应用程序等海量数据应用程序的情况下,ZGC 也具有高性能和高效工作。它确保在处理数据时不会因垃圾收集而长时间停顿。它支持 Linux、Window

  • Java 15 使 ZGC、Z 垃圾收集器成为标准功能。它是 Java 15 之前的一个实验性功能。它是低延迟、高度可扩展的垃圾收集器。 ZGC 是在 Java 11 中作为一项实验性功能引入的,因为开发人员社区认为它太大而无法提前发布。从那时起,对这个垃圾收集做了很多改进,例如 - 并发类卸载 取消提交未使用的内存 支持班级数据共享 NUMA 多线程堆Pre-touch 最大堆大小限制从 4 T

  • 有人能给我解释一下原因吗?