0

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.

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.

  1. Would GC Clean this resource up?
  2. Is there a way JVM/CLR handles these scenario's and avoid this kind of Memory corruption?

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).

Kishore Bandi
  • 5,537
  • 2
  • 31
  • 52
  • Why don't you take a look at the generated assembly code and look if the variable gets assigned in one opcode? – Neijwiert Apr 17 '19 at 08:49
  • @Neijwiert aren't both languages converting code into intermediate code (Bytecode/IL) and then uses JIT for Native generation? How can we get the assembly code for this? – Kishore Bandi Apr 17 '19 at 08:54
  • Safe points will handle this in java. Note that _if_ this could happen, then the code (and runtime) would be unworkable since it could happen at any point. Here's a link to jclarity on how to log safe points for java. Couple of years old but still valid. https://www.jclarity.com/2016/02/02/how-to-create-useful-gc-and-safepoint-logs/ – Erik Apr 17 '19 at 10:11

1 Answers1

3

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

This is the wrong assumption, GC simply won't kick in in the middle of such assignment. 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).

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). I am not aware of any tool other than WinDbg to see it.

Konrad Kokosa
  • 16,563
  • 2
  • 36
  • 58
  • Great, that explain a lot. Is there a document where we could get more info on how these "safe-points" work and how GC works with them? – Kishore Bandi Apr 17 '19 at 09:03
  • 1
    I can speak about CLR here only - it was quite undocumented but you can start from https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md. And I've described it very thoroughly in my book linked in this article - sorry for self-promoting... – Konrad Kokosa Apr 17 '19 at 09:08
  • 1
    Even for a JVM allowing garbage collection to take place at bytecode instruction granularity, there would be no problem, as the allocation leaves a reference on the operand stack and the assignment will take it from there and store it into a local variable, so at each point, the reference is within the stackframe. More generally, for the code to work, the reference must exist *somewhere* and either, the garbage collector understands that “somewhere” to recognize the existence of the reference, or it is not allowed to run while the reference is pending in that particular “somewhere”. – Holger Apr 18 '19 at 13:18