简体   繁体   English

GC如何在GC周期(Java / C#)中阻止新创建的内存/对象被清除

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

Suppose we take a sample code as below 假设我们采用以下示例代码

class Employee 
{
    int id;
    String name;
}

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

In the above code, I'm assuming the allocation of heap memory for Employee Object happens first and then its reference is assigned to the stack reference e . 在上面的代码中,我假设首先为Employee Object分配堆内存,然后将其引用分配给堆栈引用e

Is the above valid or something deep happens here? 以上是正确的还是发生了什么深渊?

If Yes, 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. 如果是,则让我们假设在堆中创建内存之后,恰好在将其引用分配给e ,GC将启动,并从GC根目录识别出没有对此新Heap内存的引用。

  1. Would GC Clean this resource up ? GC会清理此资源吗?
  2. Is there a way JVM/CLR handles these scenario's and avoid this kind of Memory corruption? JVM / CLR是否可以处理这些情况并避免这种内存损坏?

Tagging both Java & C#, as I see the logic of cleaning up in case of Mark and Sweep for both Java and C# seems to be almost same (at least in terms of identifying unused object from roots & cleaning up). 标记Java和C#,正如我所看到的,在Java和C#的Mark和Sweep情况下进行清理的逻辑似乎几乎相同(至少就从根目录识别未使用的对象并进行清理而言)。

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 然后让我们假设在堆中创建内存之后,就在将其引用分配给e之前,GC将启动,并从GC根目录中识别出没有对此新Heap内存的引用。

This is the wrong assumption, GC simply won't kick in in the middle of such assignment. 这是一个错误的假设,GC根本不会在此类分配过程中加入。 Obviously, it would be incorrect and dangerous behavior. 显然,这将是不正确和危险的行为。

And more generally, when JITtting methods, "safe-points" are injected where GC may kick in. Those are typically sub-methods calls, long loops and others (it strictly depend on JIT implementation). 更一般而言,当使用JITtting方法时,会在GC可以插入的地方注入“安全点”。这些通常是子方法调用,长循环等(严格取决于JIT实现)。

Not sure about JVM but in case of CLR it is hard to see such "GCInfo" about safe-points, even if you will grab the generated assembly code (for example by using https://sharplab.io ). 不确定JVM,但是就CLR而言,即使您将抓住生成的汇编代码(例如,通过使用https://sharplab.io ),也很难看到有关安全点的“ GCInfo”。 I am not aware of any tool other than WinDbg to see it. 除了WinDbg之外,我没有其他工具可以看到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM