固定对象是什么?

我正在尝试使用ant内存探查器查找内存泄漏,并且在一个新术语中遇到了:

固定的对象。

有人可以给我一个关于此对象是什么的简单明了的解释,如何固定/取消固定对象,以及检测谁固定了对象?

谢谢

sagie asked 2020-08-01T07:34:37Z
7个解决方案
52 votes

固定的对象是不允许移动的对象。 垃圾收集器通常通过将所有对象移动到“一个或多个群集”来压缩内存。 这是为了创建大块的可用空间。

这基本上意味着,如果其他人(外部)具有指向对象的内存地址的指针,则这可能指向随机内容-随着对象的移动。

固定对象会告知GC不能移动它。 这通常是无用的,并且仅在使用指针时才有意义-就像使用PInvoke一样。 有时,您需要将一个地址(在内存布局方面)上交到一个结构中,如果该地址在类中实现,则必须将其固定。

具体回答:

  • 您无法确定谁固定了对象。
  • 固定是通过FIXED语句完成的。 仅在不安全的代码中允许这样做。

检查:

[HTTP://MSDN.Microsoft.com/恩-US/library/发58文章21%28vs.80%29.aspx]

TomTom answered 2020-08-01T07:42:19Z
19 votes

固定对象是垃圾收集器无法移动的对象,这意味着其地址必须保持不变,因为其他人(通常是一些非托管代码)依赖于该对象位于确定的内存地址。

通常,垃圾回收器可以自由地重新定位内存中的对象。 在托管代码中,由于垃圾收集器具有访问所有引用的能力,因此可以将对象自由地重新映射到其他位置,然后更新对该对象的所有引用,以使该过程对正在运行的代码透明。 这样,GC可以更好地组织程序的内存,并在需要时对其进行压缩。

当非托管对象与您的代码进行交互时(在不安全的部分中),可能会出现以下情况:在某处指向您的一段代码的指针(例如,指向您正在处理的代码中的一段内存)的指针 外部COM调用。 无法重新映射此内存,因为COM调用期望对象位于给定的地址中,因此,如果将其移动,GC将无法以任何方式将更改通知给COM对象,从而导致访问 违规或更糟。

Jorge Córdoba answered 2020-08-01T07:42:49Z
6 votes

与非托管代码通信时使用固定对象。 在托管代码中,垃圾收集器可以自由移动存储块,因为它知道对存储块的所有引用,并且可以相应地更新它们。

与非托管代码(例如Win-API)进行通信时,指向数据或缓冲区的指针通常作为参数传递。 如果垃圾收集器可以自由移动该数据,则指针将突然变为无效。 由于将指针传输到非托管代码,因此GC无法更新指针-甚至无法知道使用该指针的位置。 为了防止内存移动并确保数据停留在非托管代码的指针所知道的位置,可以固定对象。

Anders Abel answered 2020-08-01T07:43:16Z
6 votes

固定对象的原因是,如果要调用非托管代码。

当垃圾收集器运行时,它可能会删除不再需要的对象。 这在堆中留下了一个“空”的可用空间。 然后,GC通过将其余对象一起移动来压缩堆,以确保可用空间位于一个连续的块中(有点像对硬盘进行碎片整理)。

它还会将所有引用(在托管代码中)更新为在压缩过程中已移动的任何对象。

如果您使用的是非托管代码(例如,某些外部C ++)并为其提供了指向对象的指针,则GC无法告知非托管代码对象在运行后已移动。 因此,您可以将与外部代码共享的对象标记为固定,这样就不会出现指针变为无效的问题。

Paolo answered 2020-08-01T07:43:50Z
5 votes

为了固定对象,可以使用fixed关键字:

固定语句可防止 垃圾回收器从 可移动变量。 固定声明 仅在不安全的情况下允许 上下文。

我之前看到的一个示例是将一个长值分解为字节,以便可以将其编码为串行密钥。 为了获得指针,这是在不安全的上下文中完成的。 开始出现间歇性错误是因为垃圾回收将在获取单个字节的过程中进行。 该值将被重定位,并且剩下一半的正确字节,一半的垃圾字节。

我们的解决方案是使用BitConverter类。 如果查看BitConverter类的基础代码,您将看到它使用fixed关键字固定字节数组,同时从变量获取字节。

Richard Nienaber answered 2020-08-01T07:44:24Z
4 votes

固定对象是在内存中具有固定位置的对象。

通常,垃圾回收器将压缩托管堆,这将更改对象在内存中的位置。如果您有一些非托管代码引用了您创建的某些C#对象,那么您可能希望能够绝对引用该内存位置。固定对象使您可以确定地执行此操作。

您可以使用fixed语句创建它们:[http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx]

JonC answered 2020-08-01T07:44:53Z
2 votes

从msdn得到“固定对象是垃圾收集器无法在内存中移动的对象”

[HTTP://MSDN.Microsoft.com/恩-US/library/小2脱衣服一边吃(vs.71).aspx]

CliffC answered 2020-08-01T07:45:18Z
translate from https://stackoverflow.com:/questions/2490912/what-are-pinned-objects