2

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

4 に答える 4

3
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)
        {{
            //読む
        }
    }
}
OdbcConnection.ReleaseObjectPool();

上記のコードは、「//読み取り」実行ポイントで作成されない限り、メモリリークは発生しません。GC.Collectを本番環境で使用しないでください。とにかく役に立たない可能性が高く、セルフチューニングであるため実際にGCを妨げる可能性があります。ANTSメモリプロファイラーのようなプロファイラー(または1つの無料トライアル)を入手して、オブジェクトに何がぶら下がっているのかを確認します。

リークがあるかどうかを示すためにWindowsタスクマネージャを信頼しないでください。そのためには、必ずプロファイラーを使用してください。

于 2010-08-06T00:34:15.063 に答える
2

usingステートメント内に接続、コマンド、およびリーダーを入れてみてください。

そして最後に電話OdbcConnection.ReleaseObjectPool();

注: ガベージ コレクションの実行には数分かかる場合があります。リークがないことを証明するには、GC.Collect()3 回続けて呼び出すことができます [3 回すべての世代からオブジェクトをクリアする]。

GC.Collect()ただし、パフォーマンスに大きな影響を与える可能性があるため、運用コードをそのままにしないでください。

于 2010-02-18T19:45:51.690 に答える
0

リークをどのように検出しましたか?タスクマネージャーでmemの使用量が増え、すぐに解放されない場合は、GCがすぐに起動しないか、管理対象環境でまだ解放されていない接続プールまたはハンドルがあることが原因である可能性があります。Travisが提案したANTSMemProfilerのようなメモリプロファイラーを使用することをお勧めします。試用版を入手できます。それ以外の場合は、MicrosoftCLRProfilerの基本バージョンを使用してください。

プロファイリングプロセス中にプロセスがより長く実行されるようにプロセスをロードして、問題が発生した場合に明確に表示されるようにする場合のもう1つの適切な方法。最も簡単なのは、その周りにループを配置して、上記を1000回以上実行することです。パフォーマンスモニターを使用して、対象のカウンターの一部を監視し、実行中にそれらがどのようにトレースされるかを確認することもできます。

于 2010-08-06T00:56:30.433 に答える
0

GC.Collect の呼び出しを避けるようにしてください。

自分が何をしているのかを 100% 確実に理解していない限り、ガベージ コレクターには決して触れないでください。常に覚えておいてください - ガベージ コレクターはあなたよりも賢く、実行するのに最適な時期を知っています。

于 2010-08-06T02:40:11.560 に答える