GC Roots misunderstanding?

让人想犯罪 __ 提交于 2019-12-05 18:47:57

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.

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.

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.

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