从托管的“ ref”内部指针恢复包含GC对象 [英] Recover containing GC object from managed 'ref' interior pointer

查看:128
本文介绍了从托管的“ ref”内部指针恢复包含GC对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于最新版本的 C#7 中的 ref locals ref return 新功能,该问题是新相关的:

This question is newly relevant in light of the new ref locals and ref return features in the latest versions of C# 7:

随着C#中托管(或内部)指针变量的重要性日益增强和广泛使用,有时您可能需要恢复各自包含的 Pinnable 此类指针的GC对象。例如,如果您传递的托管指针指向类型为 T 的数组元素,则可能需要数组引用 T [] 本身,以便调用(例如) Array.Copy(...)

With the increased prominence and wider use of managed--or "interior"--pointer variables in C#, occasionally you may need to recover the respective containing Pinnable GC object for such a pointer. For example, if you are passing around a managed pointer to an array element of type T, you might need the array reference T[] itself in order to call (e.g.) Array.Copy(...).


因此,在以下流行的内部/托管指针之一(的情况下),从托管代码中,是否有任何合理合法的方法来恢复包含的GC对象句柄。 ref 输出输入)使用:

So, from managed code, is there any reasonably legitimate way to recover the containing GC object handle, given either of the following prevalent interior/managed pointer (ref, out, in) uses:


  1. 指向(结构 class )的内部指针GC对象实例中的> field ;

  2. 指向( struct class的托管指针元素 T 数组 T []

  1. Interior pointer to a (struct or class) field within a GC object instance;
  2. Managed pointer to a (struct or class) element T of Array T[].



内部 .NET ,看来GC使用了以下功能: / coreclr / master / src / gc / gc.cpp

Internally in .NET, it appears that the GC uses the following function: /coreclr/master/src/gc/gc.cpp

#ifdef INTERIOR_POINTERS
// will find all heap objects (large and small)
uint8_t* gc_heap::find_object (uint8_t* interior, uint8_t* low)
{
    ....

此代码遍历了已知的GC堆,以检查指定的内部指针是否在已知GC对象分配的范围内。显然,这种方法不易从最终用户管理的代码中访问,而且据我所知,如果没有进行中的GC,甚至可能不适用。

This code walks through known GC heaps checking for whether the specified interior pointer falls within the range of the known GC object allocations. Obviously, this method is not readily accessible from end-user managed code and, for all I know, may not even be relevant if there's no GC in progress.

查看了新的 Span< T> System.Memory 库,但找不到一系列的操作序列如果您不是从一开始就提供数组句柄的话,它将恢复(例如)数组句柄(从而包含句柄被那些不同的结构压缩掉了)。在 _pinnable 是可选的情况下(例如 Span< T> ),如果您不选择-in,没有代码可以找回它。

I also looked through the new Span<T> and System.Memory libraries, but couldn't find a sequence of manipulations that would recover an (e.g.) array handle if you didn't start by providing it in the first place (whereby the containing handle gets squirreled away in those various structs). In cases where the _pinnable is optional (e.g. Span<T>), it seems that if you don't opt-in, there's no code that's able to get it back.

摘要:有什么方法可以从托管对象中恢复包含对象的句柄。

Summary: Is there any way to recover the containing object handle from a managed pointer?

[edit:]如果托管指针指向堆栈上的值类型,则(假定的)句柄恢复函数指示该指针将是完全合理的

[edit:] If the managed pointer points to a value-type on the stack, it would be perfectly reasonable for the (putative) handle recovery function to indicate failure by (e.g.) returning 'null'.

相关:C#垃圾收集器如何查找仅引用其的对象是内部指针吗?

推荐答案

不,从内部指针恢复包含对象是不可能。在GC期间,由于所谓的 brick表插入树,内部指针被转换为相应的对象。给定指定的地址,将计算适当的砖块表条目,并遍历相应的插件树以找到该地址所在的插件。最后,逐个对象地扫描该插件,以找到包含所考虑地址的插件。

No, recovery of the containing object from an interior pointer is not possible. During GC, interior pointers are translated into corresponding objects thanks to the so-called brick table and plug trees. Given a specified address, the proper brick table entry is calculated and corresponding plug tree is traversed to find the plug within which that address lives. Finally, that plug is scanned object-by-object to find the one that contains the considered address.

要点是,这些树是在GC期间构建并可用的。因此,即使存在这样的内部指针恢复 API,它也必须等待GC并且只能在之后提供答案(这似乎非常不切实际)。其他解决方案,例如线性内存扫描,显然可能会带来巨大的开销。

The point is those trees are built and available only during GC. So, even if such an "interior pointer recovery" API existed, it would have to wait for the GC and could provide an answer only afterwards (which seems very impractical). Other solutions, like linear memory scanning, would obviously possibly introduce tremendous overhead.

这篇关于从托管的“ ref”内部指针恢复包含GC对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆