<tfoot id='faQb7'></tfoot>
      <bdo id='faQb7'></bdo><ul id='faQb7'></ul>

      <small id='faQb7'></small><noframes id='faQb7'>

        <legend id='faQb7'><style id='faQb7'><dir id='faQb7'><q id='faQb7'></q></dir></style></legend>
      1. <i id='faQb7'><tr id='faQb7'><dt id='faQb7'><q id='faQb7'><span id='faQb7'><b id='faQb7'><form id='faQb7'><ins id='faQb7'></ins><ul id='faQb7'></ul><sub id='faQb7'></sub></form><legend id='faQb7'></legend><bdo id='faQb7'><pre id='faQb7'><center id='faQb7'></center></pre></bdo></b><th id='faQb7'></th></span></q></dt></tr></i><div id='faQb7'><tfoot id='faQb7'></tfoot><dl id='faQb7'><fieldset id='faQb7'></fieldset></dl></div>
      2. compaction发生后GC如何更新引用

        时间:2023-09-13

        <tfoot id='1TzqS'></tfoot>
          <bdo id='1TzqS'></bdo><ul id='1TzqS'></ul>
          <i id='1TzqS'><tr id='1TzqS'><dt id='1TzqS'><q id='1TzqS'><span id='1TzqS'><b id='1TzqS'><form id='1TzqS'><ins id='1TzqS'></ins><ul id='1TzqS'></ul><sub id='1TzqS'></sub></form><legend id='1TzqS'></legend><bdo id='1TzqS'><pre id='1TzqS'><center id='1TzqS'></center></pre></bdo></b><th id='1TzqS'></th></span></q></dt></tr></i><div id='1TzqS'><tfoot id='1TzqS'></tfoot><dl id='1TzqS'><fieldset id='1TzqS'></fieldset></dl></div>

          <small id='1TzqS'></small><noframes id='1TzqS'>

            <legend id='1TzqS'><style id='1TzqS'><dir id='1TzqS'><q id='1TzqS'></q></dir></style></legend>
                <tbody id='1TzqS'></tbody>

                  本文介绍了compaction发生后GC如何更新引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  .NET 垃圾收集器收集对象(回收它们的内存)并执行内存压缩(将内存碎片保持在最低限度).

                  The .NET Garbage Collector collects objects (reclaims their memory) and also performs memory compaction (to keep memory fragmentation to minimum).

                  我想知道,由于应用程序可能对对象有很多引用,当对象的地址由于 GC 进行压缩而发生变化时,GC(或 CLR)如何管理对对象的这些引用.

                  I am wondering, since an application may have many references to objects, how does the GC (or the CLR) manage these references to objects, when the object's address changes due to compaction being made by the GC.

                  推荐答案

                  这个概念很简单,垃圾收集器简单地更新任何对象引用并将它们重新指向移动的对象.

                  The concept is simple enough, the garbage collector simply updates any object references and re-points them to the moved object.

                  实现有点棘手,本机代码和托管代码之间没有真正的区别,它们都是机器代码.对象引用并没有什么特别之处,它只是运行时的指针.收集器需要一种可靠的方法来找到这些指针并将它们识别为引用托管对象的类型.不仅要在压缩时移动指向的对象时更新它们,还要识别实时引用以确保不会过早收集对象.

                  Implementation is a bit trickier, there is no real difference between native and managed code, they are both machine code. And there's nothing special about an object reference, it is just a pointer at runtime. What's needed is a reliable way for the collector to find these pointers back and recognize them as the kind that reference a managed object. Not just to update them when the pointed-to object gets moved while compacting, also to recognize live references that ensure that an object does not get collected too soon.

                  对于存储在 GC 堆上的类对象中存储的任何对象引用,这很简单,CLR 知道对象的布局以及哪些字段存储指针.对于存储在堆栈或 cpu 寄存器中的对象引用来说,这并不是那么简单.像局部变量和方法参数.

                  That's simple for any object references that are stored in class objects that are stored on the GC heap, the CLR knows the layout of the object and which fields store a pointer. It is not so simple for object references stored on the stack or in a cpu register. Like local variables and method arguments.

                  执行托管代码与本机代码不同的关键属性是 CLR 可以可靠地迭代托管代码拥有的堆栈帧.通过限制用于设置堆栈帧的代码类型来完成.这在本机代码中通常是不可能的,帧指针省略"优化选项特别讨厌.

                  The key property of executing managed code which makes it distinct from native code is that the CLR can reliably iterate the stack frames owned by managed code. Done by restricting the kind of code used to setup a stack frame. This is not typically possible in native code, the "frame pointer omission" optimization option is particularly nasty.

                  栈帧遍历首先让它找到存储在栈中的对象引用.并让它知道线程当前正在执行托管代码,因此也应该检查 cpu 寄存器的引用.从托管代码到本机代码的转换涉及在收集器识别的堆栈上编写一个特殊的cookie".因此它知道不应检查任何后续堆栈帧,因为它们将包含从未引用托管对象的随机指针值.

                  Stack frame walking first of all lets it finds object references stored on the stack. And lets it know that the thread is currently executing managed code so that the cpu registers should be checked for references as well. A transition from managed code to native code involves writing a special "cookie" on the stack that the collector recognizes. So it knows that any subsequent stack frames should not be checked because they'll contain random pointer values that don't ever reference a managed object.

                  启用非托管代码调试后,您可以在调试器中看到这一点.查看调用堆栈窗口并注意 [Native to Managed Transition] 和 [Managed to Native Transition] 注释.那就是识别这些cookie的调试器.对它也很重要,因为它需要知道 Locals 窗口是否可以显示任何有意义的内容.堆栈遍历也在框架中公开,请注意 StackTrace 和 StackFrame 类.并且对于沙盒非常重要,代码访问安全 (CAS) 执行堆栈遍历.

                  You can see this back in the debugger when you enable unmanaged code debugging. Look at the Call Stack window and note the [Native to Managed Transition] and [Managed to Native Transition] annotations. That's the debugger recognizing those cookies. Important for it as well since it needs to know whether or not the Locals window can display anything meaningful. The stack walk is also exposed in the framework, note the StackTrace and StackFrame classes. And it is very important for sandboxing, Code Access Security (CAS) performs stack walks.

                  这篇关于compaction发生后GC如何更新引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:托管托管代码和垃圾收集 下一篇:正在收集回调代表?

                  相关文章

                  <small id='OD5vH'></small><noframes id='OD5vH'>

                      • <bdo id='OD5vH'></bdo><ul id='OD5vH'></ul>
                      <i id='OD5vH'><tr id='OD5vH'><dt id='OD5vH'><q id='OD5vH'><span id='OD5vH'><b id='OD5vH'><form id='OD5vH'><ins id='OD5vH'></ins><ul id='OD5vH'></ul><sub id='OD5vH'></sub></form><legend id='OD5vH'></legend><bdo id='OD5vH'><pre id='OD5vH'><center id='OD5vH'></center></pre></bdo></b><th id='OD5vH'></th></span></q></dt></tr></i><div id='OD5vH'><tfoot id='OD5vH'></tfoot><dl id='OD5vH'><fieldset id='OD5vH'></fieldset></dl></div>
                    1. <legend id='OD5vH'><style id='OD5vH'><dir id='OD5vH'><q id='OD5vH'></q></dir></style></legend>
                      <tfoot id='OD5vH'></tfoot>