【发布时间】:2015-01-11 16:22:27
【问题描述】:
从mscorlib浏览PinnableObjectCache的代码时,遇到如下代码:
for (int i = 0; i < m_restockSize; i++)
{
// Make a new buffer.
object newBuffer = m_factory();
// Create space between the objects. We do this because otherwise it forms
// a single plug (group of objects) and the GC pins the entire plug making
// them NOT move to Gen1 and Gen2. By putting space between them
// we ensure that object get a chance to move independently (even if some are pinned).
var dummyObject = new object();
m_NotGen2.Add(newBuffer);
}
这让我想知道对 plug 的引用是什么意思?在尝试将对象固定在内存中时,GC 不会固定为对象指定的特定地址吗?这个plug 行为实际上在做什么?为什么需要在对象之间“留出空间”?
【问题讨论】:
-
博文blogs.msdn.com/b/maoni/archive/2005/10/03/… 中有更多信息,向下滚动到“碎片控制”。位我不完全确定它是否回答了这个问题?!
-
@MattWarren 他谈到了 Demotion,其中间隔固定对象之间的对象不会得到提升。但在这个例子中,作者故意在固定对象之间分配一个空间为了确保它们被独立提升。不幸的是,它没有谈论插头行为:\
-
看起来像是一种在内存中创建填充的方法。给定
dummyObject相当快,newBuffer之后应该有一些“清除”空间(假设分配是相邻的)。也许最小固定空间是IntPtr.Size的两倍? -
那条评论是由一个只有半点线索的微软新手程序员写的。部分准确,他被要求找到解决方法的问题是真实的。是的,在 GC 压缩算法中确实存在堵塞与间隙,当您分配几个可能被固定的缓冲区时,这是一件令人烦恼的事情。当 GC 运行不会移动时,夹在 可能 之间的那些会被取消固定。其余的评论,不,不是真的。这是 hacky 代码,它出现两次会失去一千个优雅点,它非常无害并且确实试图解决核心问题。
-
@HansPassant 您能否在答案中详细说明 GC 行为?
标签: c# .net garbage-collection .net-internals .net-4.6