【问题标题】:Static objects are pinned and cannot be reallocated by GC?静态对象被固定,不能被 GC 重新分配?
【发布时间】:2011-10-28 19:58:12
【问题描述】:

我的类中有一个静态变量,当我通过 windbg/sos 查看这个对象时,它显示这个对象为 Pinned。我假设这意味着 GC 不能在其他任何地方分配这个对象。任何想法为什么静态变量被视为固定?

这是这个变量在我的类中的声明

namespace ConsoleApplication1
{  
    class Program  
    {  
        static string Name = "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";  
    }  
}  

这是windbg的输出形式

0:004> !do 0231bb70   
Name:        System.String  
MethodTable: 6c97f92c  
EEClass:     6c6b8ba0  
Size:        418(0x1a2) bytes  
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll  
String:        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa    
Fields:    
      MT    Field   Offset                 Type VT     Attr    Value Name  
6c9828f8  4000103        4         System.Int32  1 instance      202 m_stringLength  
6c981d48  4000104        8          System.Char  1 instance       41 m_firstChar  
6c97f92c  4000105        8        System.String  0   shared   static Empty  
    >> Domain:Value  004f6588:02311228 <<  
0:004> !gcroot 0231bb70   
Scan Thread 0 OSTHread 2824  
Scan Thread 2 OSTHread 1ae0  
DOMAIN(004F6588):HANDLE(Pinned):1613f4:Root:  03312020(System.Object[])->
  0231bb70(System.String)  
DOMAIN(004F6588):HANDLE(Pinned):1613fc:Root:  03311010(System.Object[])->
  0231bb70(System.String)  

在 !gcroot 的输出中看到它显示为 HANDLE(PINNED)。我误读了这个输出吗?

【问题讨论】:

  • 为什么windbg的节目是PINNED呢?
  • 你能显示 WinDbg 的输出吗?
  • 用代码和windbg输出更新问题
  • 用字符串以外的引用对象试试。字符串是不可变的并且是 CLR 原生的。由于该值是字符串文字并且永远无法更改,因此可以对其进行特殊处理并将其放置以便永远不必移动它。
  • 是的,使用 ref 类型它不会显示为固定。

标签: c# garbage-collection sos windb


【解决方案1】:

字符串被固定的原因不是因为你有一个静态引用,而是因为你有一个字符串文字。默认情况下,字符串文字是实习的,因此您会看到它们是固定的。另请参阅this question。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2018-03-21
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    相关资源
    最近更新 更多