首页 > 解决方案 > 如何理解“重新定位可从运行代码直接访问的对象”?

问题描述

我正在研究将 gc 集成到我的 llvm 项目中,当我阅读此文档时,有一句话让我很困惑:

但是,对于希望重新定位可从运行代码直接访问的对象的收集器,需要更高的标准。

我不明白移动“重新定位可从运行代码直接访问的对象”试图做什么。

据我所知,“重定位”这个概念意味着 gc 指针指向一个对象的新位置,例如:

在 Java 中:

Foo foo = new Foo();

foo = new Foo(); // ---> a relocation happens

那么任何人都可以解释“从运行代码直接访问的重定位对象”试图做什么吗?

编辑:

关于“重定位”的概念,文档没有解释,但我找到了这个文档,它是一个由 llvm 实现的 dotnet 编译器,它解释了这个概念:

如果在 GC 期间,可能会更新 GC 指针以引用对象的新位置,则 GC 算法正在重新定位。算法更新在某些区域而不是其他区域中找到的指针。例如,堆栈中的 GC 指针可能不会更新,而堆中的 GC 指针可能是可更新的。如果算法从所有区域重新定位指针,它就是完全重新定位。当 GC 从某个内存区域重新定位指针时,它必然意味着 GC 报告在该区域中是精确的。

我不知道我是否理解“搬迁”正确,所以我将其粘贴为您提供信息。

标签: garbage-collectionllvm

解决方案


这意味着重新定位地址在函数局部变量中的对象。比如这样:

void doRelevantActions(final Thing t) {
    for(Aspect a : t.getAspects())
        if(a.isRelevant(getCurrentSituation()))
            t.doSomeAction();
}

通常, anAspect只能从 a 到达Thing。但是在那个循环中,局部变量a也到达了一个Aspect并且a可能在一个 CPU 寄存器中,所以 GC 可能必须修改一个 CPU 寄存器的值才能重新定位它Aspect

在我看来,在运行时修改函数的 CPU 寄存器需要的不仅仅是“更高的标准”。它需要一根魔杖。

我相信做这种事情的 GC 通过确保在某些时候 CPU 寄存器中没有状态来做到这一点,因此停止正在运行的线程并修改所有线程的堆栈帧就足以重新定位对象。不过,修改堆栈帧仍然不是一件简单的事情。

编辑:也许我误解了你问题的核心?也许你真的想知道什么是搬迁?假设一个对象有 100 字节大,并且在某个时候,它单独占据了 8k RAM 页,因为该页上没有其他内容可以访问。如果 GC 可以将该 100 字节对象移动到另一个 8k 页面,那么它可以释放 8k。该操作称为重定位。


推荐阅读