Question

It may be just a memory leak question. For those not familiar with WinSCP, skip ahead to question.

I am using .net assembly of WinSCP in a C++/CLI program. My program will read in a schedule file. The file instructs the program to transfer files from various locations. Some transfers could come from the same server, so my program should close the existing connection if it is a new server. If the server is the same, keep the connection to use.

As there is no Session::Close(), the document recommends to use Session::Dispose() (Refer to Session.Dispose() Documentation.) Yet when I compile, I see error message saying:

'Dispose' is not a member of 'WinSCP::Session'

Eventually I use delete session. Part of my program will then roughly look like:

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...
}

【Question】: Will there be any memory leak by deleting the object (delete GlobalClass::g_sftpSession) and create it again (GlobalClass::g_sftpSession = gcnew WinSCP::Session()) many times per minute?

From several .net resources I have read, the delete object action will mark the object to be garbage collected. When will it be done? It is entirely up to the gc mechanism. So if my program has to make connections to several sites, it has to do that delete and create several times. By the program finishes (usually in less than 1 minute), can I count on the garbage collection mechanism to clean out all memory? Reason I ask is my program will run every minute. If there is memory leak each time program is run, my machine will be out of memory very soon.

Was it helpful?

Solution

The WinSCP .NET assembly Session class has the Dispose method. Though it's probably hidden by C++/CLI. You call the Dispose indirectly using the delete. See How do you dispose of an IDisposable in Managed C++ and Calling C++/CLI delete on C# object.

Generally, even if you do not, the garbage collector will do this for you (in an unpredictable moment), as you do not keep reference to old sessions. But it definitely won't let your machine run out of memory.

On the other hand, you NEED to call the Dispose (the delete) to close the unused sessions anyway, otherwise you may run out of allowed connections to the servers (or even exhaust servers' resources).

If you want to check, if and when the session is disposed, set the Session.DebugLogPath and search a log for an entry like:

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

Your question whether there's a chance for a memory leak, when a program finishes is irrelevant. Any memory allocated by a process is released by an operating system when the process finishes. No matter what leak/bug/anything is in the program itself. See also Does the heap get freed when the program exits? Anyway, I believe your code does not leak memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top