简体   繁体   English

为什么我不应该使用GC.Collect()

[英]Why shouldn't I use GC.Collect()

I am developing an application where I work with CertAdm.dll to make connections to a Certificate Authority. 我正在开发一个与CertAdm.dll一起使用的应用程序,以建立与证书颁发机构的连接。 Sometimes I get the error "An attempt was made to open a Certification Authority database session, but there are already too many active sessions. The server may need to be configured to allow additional sessions." 有时,我会收到错误消息“试图打开证书颁发机构数据库会话,但是活动会话已太多。可能需要将服务器配置为允许其他会话。”

If I configure my connection like the code below, I dont get the error and all works fine. 如果我按照下面的代码配置连接,则不会收到错误消息,并且一切正常。

CERTADMINLib.ICertView2 cv2 = new CERTADMINLib.CCertViewClass();

try
{
    cv2.OpenConnection(srtCAConfig);
}
catch
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
    cv2.OpenConnection(srtCAConfig);
}

Now what I am wondering about is that I have read a lot where people say you shouldn't use GC.Collect(). 现在我想知道的是,我读了很多地方,人们说你不应该使用GC.Collect()。 Why shouldn't I? 我为什么不呢 It solves my problem? 它解决了我的问题吗?

All help is very appreciated. 非常感谢所有帮助。

Short answer: Garbage collection becomes less efficient the more you do it. 简短的回答:您做得越多,垃圾收集的效率就会越低。

Waiting for pending finalisers is also undesirable. 等待未决的终结器也是不希望的。 You are holding up your code to wait for an unknown number of objects to perform cleanup operations that could take an unknown amount of time. 您正在保留代码以等待未知数量的对象执行清理操作,这可能需要未知的时间。 If you fixed the underlying problem, there'd be no need to wait for any of them. 如果您解决了根本问题,则无需等待任何一个。

As for the underlying problem, when an object owns some external (scarce) resource, it's important that when you're done with it, you call the appropriate method to release the resource. 至于潜在的问题,当一个对象拥有一些外部(稀缺)资源时,重要的是,在使用完该对象后,调用适当的方法来释放该资源。 Often that's a method called Dispose(), CloseConnection() or something similar. 通常,这是一种称为Dispose(),CloseConnection()或类似方法的方法。

however, this is a COM interop object and all MSDN says is 但是,这是一个COM互操作对象,所有MSDN都说是

To close the connection, call the Release function (C++) or set the object to Nothing (Visual Basic). 若要关闭连接,请调用Release函数(C ++)或将对象设置为Nothing(Visual Basic)。

In .NET, the equivalent is to call System.Runtime.InteropServices.Marshal.ReleaseComObject(cv2). 在.NET中,等效项是调用System.Runtime.InteropServices.Marshal.ReleaseComObject(cv2)。 Once you've done that, the object referred to by cv2 is invalid, so don't call it again. 完成此操作后,cv2引用的对象无效,因此不要再次调用它。

Maybe it solves your problem because of incorrect work with connections in your class. 也许是由于班级中的连接操作不正确而解决了您的问题。

Try to examine all about connections in your app, see where they are opened and where closed - I think that you don't close connections / don't clear resources that are used by your connections. 尝试检查有关应用程序中连接的所有信息,查看它们在何处打开和在何处关闭-我认为您不关闭连接/不清除连接使用的资源。

I think you are not closing the connections after opening them and finally it exceeds the maximum number of connections that can be open at a time. 我认为您在打开连接后并没有关闭连接,最后它超出了一次可以打开的最大连接数。 When you give GC.Collect(), each and every time the connection object is forcefully collected , because of which you cannot reuse the already open connection. 提供GC.Collect()时,每次都会强制收集连接对象,因此,您无法重用已经打开的连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM