0

現在、.NetベースのWindowsサービスの1つがメモリを大量に消費しているという問題が発生しています。

「データベース」キャッシング手法を使用することを決定したキャッシングの実装に関係していることはほぼ間違いありません。サービスの起動時にキャッシュ値を最初にロードする方法に問題が発生しています。

これがコンセプトです...

  • クラス:サービス 運用:開始

  • クラス:キャッシュローダー 操作:LoadCache

  • クラス: DataAccessLayer操作:Store_Cache_in_DB

...そして理由を聞かないでください...

  • A)キャッシュローダーは、サービスの「start」メソッドでローカル変数として「更新」されます。
  • B)DataAccessLayerはサービスに対して静的です(IOC経由のシングルトン)

したがって、コードは次のようになります

サービス

start()
{
    _cacheLoader = new Cacheloader(_dataAccessLayer); 
    _cacheLoader.LoadCache();
}

キャッシュローダー

LoadCache()
{
    var entities = _dataAccessLayer.FindEntitiesForCache(); 
    _dataAccessLayer.Store_Cache_in_DB(entities); 
}

DataAccessLayer

Store_Cache_in_DB(List<Entity> entities)
{
    using(someConnection)
    {
        stored entities in datatable
        pass database to sproc that stores each entity
    }       
}   

したがって、ここでの私の懸念は、Store_Cache_in_DBメソッドを介して静的DataAccessLayerオブジェクトに渡される「エンティティ」にあります。どういうわけか、静的クラスで参照されているため、ガベージコレクターがこれらをクリーンアップしないのではないかと思います。この場合、最初にエンティティをローカル変数に割り当てると便利です...

DataAccessLayer:

Store_Cache_in_DB(List<Entity> entities)
{
    var cachedEntities = entities;

    using(someConnection)
    {
        stored cachedEntities in datatable
        pass database to sproc that stores each entity
    }       
} 

...うまくいけば、これで私の問題が解決するでしょう。これが私のメモリ消費量が非常に多い理由ではない場合、他に何かアイデアはありますか?繰り返しになりますが、このキャッシング手法が実行者であると確信しています。

前もって感謝します!

4

1 に答える 1

1

この場合、最初にエンティティをローカル変数に割り当てると役立つでしょうか...

ローカルを使用しても何も変わりません。ユーザー コードから同じオブジェクト インスタンスに到達できます。

これがガベージコレクションされないようにする唯一の部分は、ここで起こることです:

using(someConnection)
{
    stored cachedEntities in datatable
    pass database to sproc that stores each entity
}       

entities持続する変数に保持されると、後で収集されなくなります。

これが私のメモリ消費量が非常に多い理由ではない場合、他のアイデアはありますか?

これをメモリプロファイラの下で実行することをお勧めします。これにより、何がメモリに保持されているかが正確にわかります。

于 2012-06-22T21:57:03.760 に答える