删除任何内存泄漏并多次创建相同的对象

时间:2014-04-23 04:19:23

标签: memory-leaks garbage-collection c++-cli winscp winscp-net

这可能只是一个内存泄漏问题。对于那些不熟悉WinSCP的人,请直接提问。

我在C ++ / CLI程序中使用WinSCP的.net程序集。我的程序将读入计划文件。该文件指示程序从各个位置传输文件。某些传输可能来自同一台服务器,因此我的程序应该关闭现有连接(如果它是新服务器)。如果服务器相同,请保持连接使用。

由于没有Session::Close(),文档建议使用Session::Dispose()(请参阅Session.Dispose() Documentation。)然而,当我编译时,我看到错误消息说:

  

'处置'不是' WinSCP :: Session'

的成员

最终我使用delete session。我的程序的一部分将大致如下:

void Transfer(String ^ sAction, String ^ sMode, 
              String ^ sSource_Server, String ^ sSource_Path, 
              String ^ sDest_Server, String ^ sDest_Path, 
              bool bDelDir, bool bDelFile )
{
    if ((GlobalClass::g_sFtp_Server != sSource_Server && sAction == "G")
       || (GloblaClass::g_sFtp_Server != sDest_Server && sAction == "P"))
    {
        // Close existing connection first.
        if (GlobalClass::g_sftpSession != nullptr)
            delete GlobalClass::g_sftpSession;

        if (GlobalClass::g_sftpSessionOptions != nullptr)
            // Reuse the object
            GlobalClass::g_sftpSessionOptions->HostName = sSource_Server;
        else
        {
            // Recreate object and fill in detail
            GlobalClass::g_sftpSessionOptions = gcnew WinSCP::SessionOptions();
            GlobalClass::g_sftpSessionOptions->Protocol ....
            GlobalClass::g_sftpSessionOptions->HostName ....
        }

        // Create new session
        GlobalClass::g_sftpSession = gcnew WinSCP::Session();
        GlobalClass::g_sftpSession->Open(GlobalClass::g_sftpSessionOptions);

        // Set GlobalClass::g_sFtp_Server
    }

    // Transfer files accordingly...
}

【问题】:删除对象(delete GlobalClass::g_sftpSession)并再次创建(GlobalClass::g_sftpSession = gcnew WinSCP::Session())每分钟多次会有内存泄漏吗?

从我读过的几个.net资源中,删除对象操作会将对象标记为垃圾回收。什么时候会这样?这完全取决于gc机制。因此,如果我的程序必须连接到多个站点,则必须执行多次删除和创建。 通过程序完成(通常在不到1分钟内),我可以依靠垃圾收集机制来清理所有内存吗?我问的原因是我的程序会每分钟运行一次。如果每次运行程序时都有内存泄漏,我的机器很快就会内存不足。

1 个答案:

答案 0 :(得分:1)

WinSCP .NET程序集Session类具有Dispose方法。虽然它可能被C ++ / CLI隐藏了。您使用Dispose间接调用delete。请参阅How do you dispose of an IDisposable in Managed C++Calling C++/CLI delete on C# object

通常,即使你不这样做,垃圾收集器也会为你做这件事(在一个不可预测的时刻),因为你不会继续引用旧会话。但它绝对不会让你的机器耗尽内存。

另一方面,您需要调用Disposedelete)来关闭未使用的会话,否则您可能会耗尽与服务器的连接(甚至是排气服务器)资源)。

如果要检查,是否以及何时处理会话,请设置Session.DebugLogPath并在日志中搜索以下条目:

  

[2014-04-23 08:08:50.756Z] [000a] Session.Dispose entering

您的问题是否存在内存泄漏的可能性,当程序完成时无关紧要。进程分配的任何内存在进程完成时由操作系统释放。无论什么泄漏/错误/程序本身的任何东西。另请参阅Does the heap get freed when the program exits?无论如何,我相信您的代码不会泄漏内存。