Очистка ODBC DSN в C # .NET - PullRequest
       46

Очистка ODBC DSN в C # .NET

2 голосов
/ 25 августа 2009

Я использую C # и OBDC DSN для подключения к базе данных Paradox. Кажется, у меня течет память, если я открываю и закрываю каждое соединение.

Мой код в основном:

            csb.Dsn = "DNSName";
            OdbcConnection con = new OdbcConnection(csb.ConnectionString);
            con.Open();

            OdbcCommand comm= new OdbcCommand("SELECT * FROM Tabl", con);
            OdbcDataReader reader= null;
            try
            {
                reader= comm.ExecuteReader();
                for (int count = 0; (count < 5 && reader.Read()); ++count)
                {
                    //Read
                }
            }
            finally
            {
                if (reader!= null)
                {
                    reader.Close();
                    reader.Dispose();
                }
                if (comm!= null)
                {
                    con.Close();
                    con.Dispose();
                    OdbcConnection.ReleaseObjectPool();
                    GC.Collect();
                    comm.Dispose();
                }
            }

Есть идеи или предложения?

Обновление 1

Я изменил его для использования с использованием статистики, все еще утечки.

Ответы [ 4 ]

3 голосов
/ 06 августа 2010
using (var connection = new OdbcConnection(csb.ConnectionString))
{
    connection.Open();
    using (var command = new OdbcCommand("SELECT * FROM Tabl", connection))
    using (var reader =  command.ExecuteReader())
    {
        for (var count = 0; (count < 5 && reader.Read()); ++count)
        {
            //Read
        }
    }
}
OdbcConnection.ReleaseObjectPool();

В приведенном выше коде нет утечки памяти, если она не создана в точке исключения "// Read". GC.Collect никогда не следует использовать в производстве; это, скорее всего, не поможет в любом случае и может фактически помешать GC, поскольку он самонастраивается. Возьмите профилировщик (или бесплатную пробную версию), например ANTS Memory Profiler и посмотрите, что висит на ваших объектах.

Не доверяйте диспетчеру задач Windows, чтобы показать, есть ли у вас утечка . Для этого обязательно используйте профилировщик.

2 голосов
/ 18 февраля 2010

Попробуйте поместить соединение, команду и считыватель в операторы using.

Тогда звоните OdbcConnection.ReleaseObjectPool(); в конце.

Примечание: сборка мусора может занять несколько минут. Чтобы доказать отсутствие утечки, вы можете вызвать GC.Collect() три раза подряд [три раза, чтобы очистить объекты через все три поколения].

Не оставляйте GC.Collect() в производственном коде, потому что он может сильно повлиять на производительность.

0 голосов
/ 06 августа 2010

Старайтесь не вызывать GC.Collect

Никогда не прикасайтесь к сборщику мусора, если вы не уверены на 100%, что знаете, что делаете. Всегда помните - сборщик мусора умнее вас, и он знает лучшее время для запуска.

0 голосов
/ 06 августа 2010

Как вы обнаружили утечку? Иногда использование mem увеличивается в диспетчере задач и не освобождается немедленно, возможно, из-за того, что GC не работает сразу или у вас есть пул или дескриптор соединения, которые еще не были освобождены в управляемой среде. Я предлагаю вам использовать профилировщик памяти, такой как ANTS Mem Profiler, предложенный Travis. Вы можете получить пробную версию, в противном случае используйте базовую версию от Microsoft CLRProfiler.

Еще одна хорошая мера, если загружать процесс так, чтобы он выполнялся дольше во время процесса профилирования, чтобы при наличии проблем он был четко показан. Самое простое - обернуть его так, что, скажем, выполнить вышеописанное 1000 или более раз. Вы также можете использовать монитор производительности, чтобы отслеживать некоторые интересующие вас счетчики и видеть, как они отслеживаются во время выполнения.

...