【问题标题】:Can a heap object whose initial address is not stored be protected from garbage collection?可以保护未存储初始地址的堆对象免受垃圾收集吗?
【发布时间】:2017-04-28 00:54:16
【问题描述】:

假设

  • 我正在修改别人的C程序;
  • 垃圾收集器处于活动状态;
  • 堆上存在我不希望垃圾收集器回收的对象;和
  • 对象在程序退出之前一直存在,因此没有必要对其进行 free()。

我必须存储对象的初始地址吗?假设我不关心初始地址。相反,假设我只关心指向对象内部的一些指针,并且这些指针就是我存储的全部。假设我把初始地址扔掉了。

垃圾收集器会收割我的对象吗?

其他信息

据我所知,该程序现在不收集垃圾。但是,如果程序的未来版本开始收集垃圾,那么我今天添加的代码可能会突然变成一个难以发现的错误。我不想制造一个难以发现的错误;但该程序是一个古老的、稳定的程序,成千上万的用户已经使用了很多年。因此,已知该程序在各种实际条件下都可以正常运行。重新设计不是一种选择。

该程序使用全局数据结构,它从不打扰 free()。这是我必须工作的设计。

如果你想知道:我希望存储的指针——指向对象内部的指针——恰好指向 ASCII 字符串中的单词。我只关心单词,而不关心整个字符串。特别是,我不关心字符串开头的空格,这就是为什么我不关心字符串的初始地址;但是垃圾收集器可能会无意中关心,不是吗?

存储一个我和其他任何人都不会使用的指针链接列表似乎很愚蠢,只是为了抵御一个不存在的假设垃圾收集器;但如果真的有必要,我会存储列表。

还是我的担心毫无根据?无论如何,没有人在旧的 C 程序中添加垃圾收集吗?

【问题讨论】:

  • C?垃圾收集?不计算...
  • @John3136:就我个人而言,我对垃圾收集知之甚少,这就是我问的原因。然而,无处不在的 Hans-J. Boehm seems to think C 可以进行垃圾收集。为什么他这么认为,我不知道。我至少和你一样困惑。
  • 一切皆有可能——一直如此。为什么你认为你需要担心它?
  • @John3136:有问题的错误可能是在数千个面向公众的服务器上引发堆栈粉碎攻击,这是一个潜在的安全漏洞。
  • 鉴于您只存储指向结构内部的指针,您何时以及如何访问结构开头的数据?如果答案是“你不知道”,那么为什么要在指向内部的最低地址指针之前存储数据,从而避免焦虑。如果您确实访问了开头,您可以执行诸如在结构中添加指向结构开头的指针之类的操作吗?这些对象只有一个,还是有很多?如果只有一个,您当然可以简单地在某处存储一个指向它开头的指针,以防止 GC 收集它。

标签: c pointers garbage-collection


【解决方案1】:

让我们抛开一个事实,一个使用allocate()而不是free()的程序很难被称为“稳定”;

让我们抛开这样一个事实,即向现有的大型 C 程序添加垃圾收集是一种“如果你去了,你会发现只有痛苦”的情况。

你的问题的答案是:

这取决于您的垃圾收集器的工作方式。

如果它是外来的,它可能会扫描内存并寻找指向堆内任何位置的指针,而不仅仅是指向内存块的开头。在这种情况下,您将被覆盖,因为指向字符串中间的指针足以将字符串锚定在内存中。 (防止它被垃圾收集。)

如果它不是那么奇特,那么它只会寻找指向内存块开头的指针。 (这是一件相当明智的事情。)在这种情况下,不,除非您维护指向对象本身的指针,否则您的对象不会被锚定。

就我个人而言,我什至不会尝试使用异国情调的垃圾收集器,但这就是我。

【讨论】:

  • +1 我什至不会尝试使用异国情调的垃圾收集器。只是我不知道一些未来开发者在这个程序上的黑客可能会尝试什么。但是,是的,也许这不值得担心。我只注意到Hans-J. Boehm of the C++ standards committee seems to worry about it, 所以我想我最好问一下。
  • 关于稳定性,我倾向于同意你的观点,但我所说的稳定性是另一种类型:该程序已在数千台面向公众的服务器上运行了 20 年;它在实践中适用于很多人。该程序现在可能正在您和我进行此对话的服务器上运行。我宁愿不对服务器崩溃负责!
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多