GC 如何阻止新创建的 memory/objects 在 GC 循环期间进行清理 (Java/C#)

How does GC stop newly created memory/objects from cleaning up during a GC Cycle (Java/C#)

假设我们采用如下示例代码

class Employee 
{
    int id;
    String name;
}

Employee e = new Employee(1, "NewEmployee");

在上面的代码中,我假设首先为 Employee 对象分配堆内存,然后将其引用分配给堆栈引用 e

以上是有效的还是这里发生了一些深刻的事情?

如果是,那么让我们假设在堆中创建内存之后,就在其引用分配给 e 之前,GC 启动并确定没有来自 GC 根的对这个新堆内存的引用.

  1. GC 会清理这个资源吗
  2. 有没有办法JVM/CLR处理这些情况并避免这种内存损坏?

同时标记 Java 和 C#,正如我所见,Java 和 C# 的标记和清除清理逻辑似乎几乎相同(至少在识别方面)根中未使用的对象并清理)。

Then lets assume right after the memory creation in heap and just before its reference is assigned to e, a GC kicks in and identifies there are no references to this new Heap memory from GC roots

这是错误的假设,GC 根本不会在此类分配的中间启动。显然,这是不正确和危险的行为。

更一般地说,当 JITtting 方法时,"safe-points" 被注入 GC 可能启动的地方。这些通常是子方法调用、长循环和其他(它严格取决于 JIT 实现)。

不确定 JVM,但在 CLR 的情况下,很难看到 "GCInfo" 关于安全点,即使您将获取生成的汇编代码(例如通过使用 https://sharplab.io) .我不知道除了 WinDbg 之外还有什么工具可以看到它。