qqq*_*qqq 1 c# garbage-collection memory-management memory-pressure
使用 C# 语言的哪些机制将对象的实例传递给GC.AddMemoryPressure方法?
我通过 C# book在CLR 中遇到了以下代码示例:
private sealed class BigNativeResource {
private readonly Int32 m_size;
public BigNativeResource(Int32 size) {
m_size = size;
// Make the GC think the object is physically bigger
if (m_size > 0) GC.AddMemoryPressure(m_size);
Console.WriteLine("BigNativeResource create.");
}
~BigNativeResource() {
// Make the GC think the object released more memory
if (m_size > 0) GC.RemoveMemoryPressure(m_size);
Console.WriteLine("BigNativeResource destroy.");
}
}
Run Code Online (Sandbox Code Playgroud)
我无法理解我们如何将一个对象的实例与其增加的压力相关联。我没有看到对象引用被传递给GC.AddMemoryPressure. 我们是否将增加的内存压力 (amp) 与一个对象联系起来?
此外,我认为调用GC.RemoveMemoryPressure(m_size);. 从字面上看它应该没有用。让我解释一下自己。有两种可能:对象实例之间存在关联或不存在关联。
在前一种情况下,GC 现在应该m_size确定优先级并决定何时进行收集。因此,它绝对应该自行消除内存压力(否则对于 GC 意味着什么remove an object while taking into an account the amp?)。
在后一种情况下,根本不清楚添加和删除放大器的用途。GC 只能处理定义为类实例的根。即GC只能收集对象。因此,如果对象和放大器之间没有关联,我看不出放大器如何影响 GC(所以我假设存在关联)。
我无法理解我们如何将一个对象的实例与其增加的压力相关联。
对象的实例通过调用将其添加的压力与对自身的引用相关联AddMemoryPressure。该对象已经与自身具有同一性!添加和删除压力的代码知道是什么this。
我没有看到传递给 GC.AddMemoryPressure 的对象引用。
正确的。没有必要额外的压力和任何物体之间的关联,也不管是否存在与否,GC并不需要知道这些信息来采取适当的行动。
我们是否将增加的内存压力 (amp) 与一个对象联系起来?
GC 没有。如果您的代码是这样,那就是您的代码的责任。
此外,我没有看到任何理由打电话给
GC.RemoveMemoryPressure(m_size)
这是为了让 GC 知道额外的压力已经消失。
我看不出放大器会如何影响 GC
它通过增加压力影响GC!
我认为对这里发生的事情存在根本性的误解。
增加内存压力只是告诉 GC 有关于内存分配的事实你知道,而 GC 不知道,但与 GC 的动作有关。不要求增加的内存压力与任何对象的任何实例相关联或与任何对象的生命周期相关联。
您发布的代码是一种常见模式:一个对象具有与每个实例关联的额外内存,它在分配额外内存时增加了相应的压力,并在释放额外内存时将其删除。但是不要求附加压力与一个或多个特定对象相关联。如果您在static void Main()方法中添加了一堆非托管内存分配,您可能会决定添加与之对应的内存压力,但没有与该额外压力相关联的对象。