Столкнулся с очень непонятной проблемой...
При работе написанного мной приложения (.NET C#) начинает течь память, но не в самом приложении, а в системном процессе csrss.exe (!)...
Приложение работает как сервис и постоянно опрашивает удаленные сервера, читает с них файлы следующим способом: монтирует, например, шару "C$" на свой сетевой диск, читает нужные файлы, затем отмонтирует. Все это работает в нескольких параллельных потоках (5 потоков), поскольку серверов много (около 150) и опрос идет каждые 5 минут.
Методом комментирования всего по порядку было выяснено, что память начинает течь именно в функции монтирования (или размонтирования) дисков.
После плясок с бубном и попыток обнаружить неосвобождаемые ресурсы я переписал эту функцию с использованием другого (другой библиотеки) способа - через прямой вызов WinAPI.
К сожалению, это не помогло и утекать оно не перестало.. 
 
  
 Привожу ниже оба примера для наглядности.
Первый - с использованием Windows Script Host (IWshRuntimeLibrary) - "вредный" вызов обозначил "// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
using System.IO;
using IWshRuntimeLibrary;
// ...
namespace Test1
{
class Test1
{
// ...
private static System.Collections.Generic.List<char> mountDrives=new List<char>(); // Will contain drive letters that mounted by this appication
private const string listMountLetters = "GHIJKLMNOPQRSTUVWXYZ"; // We can use these drives to mount on remote PCs
public char MountDrive(string server, string relpath, string user, string pass)
{
    logger.Debug("MountDrive start. server='" + server + "', path='" + relpath + "'");
    char driveLetter = ' ';
    const int MOUNTRETRYMAXCOUNT = 10; // Try some times (wait if anyone free drive letter)
    WshNetworkClass owNetwork = null;
    try
    {
        owNetwork = new WshNetworkClass();
        for (int retryc = 0; retryc < MOUNTRETRYMAXCOUNT; retryc++)
        {
            foreach (char curd in listMountLetters)
            {
                if (mountDrives.Contains(curd)) continue; // We're already using this drive
                try
                {
                    DriveType dt = DriveType.Unknown;
                    foreach (System.IO.DriveInfo di in System.IO.DriveInfo.GetDrives())
                    {
                        if (di.Name == curd + ":\\")
                        {
                            dt = di.DriveType;
                            break;
                        }
                    }
                    if (dt != DriveType.Unknown) continue;
                    driveLetter = curd;
                    WshNetworkClass owNetwork = new WshNetworkClass();
                    object obj1 = false;
                    object ouser = server + "\\" + user, opass = pass;
                    if (user.Contains("\\"))
                        ouser = user; // domain user - do not concatenate with server's name
                    owNetwork.MapNetworkDrive(curd + ":", "\\\\" + server + "\\" + relpath, ref obj1, ref ouser, ref opass); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    mountDrives.Add(driveLetter);
                    break;
                }
                catch (System.Runtime.InteropServices.COMException cex)
                {
                    driveLetter = ' ';
                    switch ((uint)cex.ErrorCode)
                    {
                        case 0x800704B3:
                            logger.Error("Server '" + server + "' or its shared folder '" + relpath + "' is not available !");
                            return ' ';
                        case 0x8007052E:
                            logger.Error("User or password is wrong for server '" + server + "'!");
                            return ' ';
                        case 0x800704C3:
                            logger.Error("Multiple connections to a server '" + server + "' or shared resource by the same user!");
                            return ' ';
                        case 0x8007089A:
                            logger.Error("The specified username is invalid for server '" + server + "'!");
                            return ' ';
                        default:
                            //
                            break;
                    }
                    logger.Debug("MountDrive cex: " + cex.ToString());
                }
                catch (Exception ex)
                {
                    logger.Debug("MountDrive: Exception : " + ex.ToString());
                    driveLetter = ' ';
                    continue;
                }
            }
            if (driveLetter != ' ') break;
            else if (retryc < MOUNTRETRYMAXCOUNT - 1)
                System.Threading.Thread.Sleep(3000); // Sleep before next retry
        }
    }
    finally
    {
        if (owNetwork != null)
            if (System.Runtime.InteropServices.Marshal.IsComObject(owNetwork))
                System.Runtime.InteropServices.Marshal.ReleaseComObject(owNetwork);
    }
    logger.Debug("MountDrive end. driveLetter='" + driveLetter + "'");
    return driveLetter;
}
public bool UnMountDrive(char letter)
{
    logger.Debug("UnMountDrive start. letter='" + letter + "'");
    WshNetworkClass owNetwork = null;
    try
    {
        owNetwork = new WshNetworkClass();
        object obj1 = true, obj2 = false;
        owNetwork.RemoveNetworkDrive(letter + ":", ref obj1, ref obj2); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        mountDrives.Remove(letter);
    }
    catch (Exception ex)
    {
        logger.Error("UnMountDrive('" + letter + "'): Exception: " + ex.ToString());
    }
    finally
    {
        if (owNetwork != null)
            if (System.Runtime.InteropServices.Marshal.IsComObject(owNetwork))
                System.Runtime.InteropServices.Marshal.ReleaseComObject(owNetwork);
    }
    logger.Debug("UnMountDrive end");
    return true;
}
}
}
Второй - с использованием Win32API: WNetAddConnection2:
using System.IO;
using System.Runtime.InteropServices;
// ...
namespace Test1
{
class Test1
{
// ...
private static System.Collections.Generic.List<char> mountDrives=new List<char>(); // Will contain drive letters that mounted by this appication
private const string listMountLetters = "GHIJKLMNOPQRSTUVWXYZ"; // We can use these drives to mount on remote PCs
[StructLayout(LayoutKind.Sequential)]
public struct NETRESOURCEA
{
    public int dwScope;
    public int dwType;
    public int dwDisplayType;
    public int dwUsage;
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpLocalName;
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpRemoteName;
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpComment;
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpProvider;
}
[DllImport("mpr.dll", CharSet = CharSet.Auto)]
public static extern int WNetAddConnection2A(
    [MarshalAs(UnmanagedType.LPArray)] NETRESOURCEA[] lpNetResource,
    [MarshalAs(UnmanagedType.LPStr)] string lpPassword,
    [MarshalAs(UnmanagedType.LPStr)] string UserName,
    int dwFlags);
[DllImport("mpr.dll", CharSet = CharSet.Auto)]
public static extern int WNetCancelConnection2A(
    [MarshalAs(UnmanagedType.LPStr)] string lpName,
    int dwFlags,
    int fForce);
public char MountDrive(string server, string relpath, string user, string pass)
{
    logger.Debug("MountDrive start. server='" + server + "', path='" + relpath + "'");
    char driveLetter = ' ';
    const int MOUNTRETRYMAXCOUNT = 10; // Try some times (wait if anyone free drive letter)
    for (int retryc = 0; retryc < MOUNTRETRYMAXCOUNT; retryc++)
    {
        foreach (char curd in listMountLetters)
        {
            if (mountDrives.Contains(curd)) continue; // We're already using this drive
            try
            {
                NETRESOURCEA[] n = new NETRESOURCEA[1];
                n[0] = new NETRESOURCEA();
                n[0].dwType = 1;
                int dwFlags = 4;
                n[0].lpLocalName = curd + ":";
                n[0].lpRemoteName = "\\\\" + server + "\\" + relpath;
                n[0].lpProvider = null;
                int res = WNetAddConnection2A(n, pass, user, dwFlags);  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                logger.Info("MountDrive, code=" + res.ToString());
                if (res != 0) throw new Exception("error mount, code=" + res.ToString());
                driveLetter = curd;
                mountDrives.Add(driveLetter);
                break;
            }
            catch (Exception mex)
            {
                logger.Debug("MountDrive: Exception : " + mex.ToString());
                driveLetter = ' ';
                continue;
            }
        }
        if (driveLetter != ' ') break;
        else if (retryc < MOUNTRETRYMAXCOUNT - 1)
            System.Threading.Thread.Sleep(3000); // Sleep before next retry
    }
    logger.Debug("MountDrive end. driveLetter='" + driveLetter + "'");
    return driveLetter;
}
public bool UnMountDrive(char letter)
{
    logger.Debug("UnMountDrive start. letter='" + letter + "'");
    try
    {
        int rv = WNetCancelConnection2A(letter + ":", 0, 1); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        mountDrives.Remove(letter);
    }
    catch (Exception ex)
    {
        logger.Error("UnMountDrive('" + letter + "'): Exception: " + ex.ToString());
    }
    logger.Debug("UnMountDrive end");
    return true;
}
Память утекает здорово - около 2 Gb (!) за 3 дня 
 Поскольку она течет в системном процессе - помогает только ребут всего сервера, что очень напрягает.
ЧТО я делаю неправильно? Что нужно освобождать еще?
Как вариант, можно отказаться от монтирования диска и читать файлы напрямую через UNC-путь, но тогда нужно каким-то образом имперсонировать юзера, под которым соединяться с сервером.
Добавлено через 3 минуты и 8 секунд:Вот скриншот для примера: