GC Roots misunderstanding?

末鹿安然 提交于 2019-12-07 14:37:21

问题


I know that Roots are :

  • static fields
  • method parameters
  • local fielfs
  • f-queue which also holds a pointer to the " going to be finilized" objects
  • cpu registers <=???

Now lets talk about registers.

the code whch they can contain is like :

mov bx, 0034h   ; bx = 52 (stored in 16 bits)
mov cl, bl      ; cl = lower 8-bits of bx
mov eax, ecx
call print_int

but wait !

If im not mistaken , this is the actually code which was Holding those those static , local and parameters - from the first place !

So why to write this TWICE ? ( or from another direction ?)

Why to write ( for example )

  Foo f = new Foo();

**and also** 

mov bx, 0034h   //<-------- represents the `f` address or something like that 

edit

my question about registers comes from here :


回答1:


Consider

string sentence = ...
int wordCount = sentence.Split(' ').Length;

String.Split() produces an array, it must be kept reachable for (part of ) this statement. But there is no variable or parameter pointing to it, the optimizer will most likely keep the reference in a register.

So CPU (address) registers must be considered part of the roots.




回答2:


The registers only temporary hold the values of variables.

For example when you create an object and store the reference in a variable:

Foo f = new Foo();

Whats happening is that the constructor is called, and returns the reference to the object. At this stage the reference only exists in a register. Then the content of the register is copied into the variable, so now the reference exists both in the register and in the variable. Then the register goes on and is used for something else, so then the reference only exists in the variable.


Note also that it's not only the values that are currently in the registers that are roots. Every thread has its own set of registers that are switch out to memory when the thread is not running, and all those sets of register values are also roots.




回答3:


Because the JIT compiler might optimize certain parts away not to use the stacks but directly go to the register.

Lets take a method call for example:

object a = new object(), b = new object(), c = new object();
DoSomething(a, b, c);

The JIT compiler will try to put as many paramaters as possible into a register rahter than pushing them on the stack. A sample built locally on X86 reveals:

00000082  push        dword ptr [ebp-10h] 
00000085  mov         ecx,dword ptr [ebp-8] 
00000088  mov         edx,dword ptr [ebp-0Ch] 
0000008b  call        dword ptr ds:[00742078h] 

Now there are way more complex corner cases, think about array/object accessing.



来源:https://stackoverflow.com/questions/9938186/gc-roots-misunderstanding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!