首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >抑制GC内存优化

抑制GC内存优化
EN

Stack Overflow用户
提问于 2012-12-30 18:07:52
回答 3查看 271关注 0票数 2

我正在编写一个程序,它在多线程中调用多个基于C的函数(p/Invoke)。

有时,程序会因访问冲突错误而崩溃。我的第一个想法是GC优化了内存,并将C函数正在处理的内存块移动到不同的位置。

我想要做的是让GC工作,但禁用它移动(碎片整理)内存的部分。

有没有办法做到这一点?

EN

回答 3

Stack Overflow用户

发布于 2012-12-31 00:32:30

正如其他答案所说,要做的第一件事是确保您正确地固定对象。假设你已经这样做了,还会出什么问题呢?

代码语言:javascript
复制
class C
{
    public int handle;
    ...
    ~C() { InteropLibrary.DestroyHandle(handle); }
}

void M()
{
    C c = GetSomeObjectUsefulInUnmanagedCode();
    D d = InteropLibrary.UnmanagedMethodThatUsesHandle(c);
    // COMMENT
    d.DoSomethingWithStoredHandle();
}

如果垃圾收集发生在COMMENT (*),该怎么办?垃圾收集器可以自由地说“嘿,这个方法中再也不会引用局部变量c了;我可以大刀阔斧地把它当作死了!”如果终结器运行并且句柄被销毁,那么当最后一个方法运行时,它访问被销毁的句柄并崩溃。

要解决这个罕见但可能出现的问题,您可以使用GC.KeepAlive告诉垃圾收集器在清理特定引用时不要太积极。如果您让c一直存活到方法的末尾,那么您就知道它的析构函数不可能运行。

(*)当然,GC运行在不同的线程上,并且可以在任何时候运行。GC可以中断和不能中断的操作的细节很复杂,您不应该依赖这些实现细节来确保正确性。

票数 5
EN

Stack Overflow用户

发布于 2012-12-30 18:28:10

在大多数情况下,可以使用fixed关键字。

从埃里克·利伯特的新blog来看,至少还有两种可能性:

使用外部非托管分配器(如AllocHGlobal )使用GCHandle分配内存

请注意,在这两个选项中,您需要确保正确释放内存。

顺便说一句,如果您的问题是移动了一小部分内存(导致访问冲突),那么解决方案几乎永远不会禁用整个移动内存部分。

票数 2
EN

Stack Overflow用户

发布于 2012-12-30 18:13:54

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14089848

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档