none
sessionStateでStateServerを設定するとOutOfMemoryExceptionが発生 RRS feed

  • 質問

  • ASP.NETでセッション状態を<sessionState mode="StateServer" />として、CSVファイルから取得した500~5000件前後のレコードをDataTable→Sessionへ格納後、何度も他画面遷移してSessionデータの入出力や、CSVファイルの読み替え処理を何度も繰り返したところ、高い頻度でOutOfMemoryExceptionが発生します。
    スタックトレースの出力内容は、幾つかのパターンがあるのですが、直接的な例外発生箇所は必ずStringBuilderのコンストラクタ内部であり、スタックトレースの途中には必ずSystem.Web.Util.AltSerializationクラスというMSDNライブラリでみたことない(?)クラスのメソッドを通ります。
    なお本処理はいろいろと重たい処理が多く、なかには1~3分近く時間がかかる処理もあります。
     
    同様な投稿System.OutOfMemoryException の例外を読ませて頂き、/3GBスイッチ・w3wp.exeプロセスメモリー使用量のチェック(最大650MBぐらい)、Dispose利用の有無、アセンブリ数などの確認を行ったつもりなのですが、OutOfMemoryExceptionを回避できません。
    また今回のケースはセッション状態がInProcでは起こらないため、SessionState関連での設定不良か、シリアライズ化されたセッションデータを何度も出し入れしたため大きなオブジェクト ヒープの断片化をおこしている?、などとは考えていますが、原因特定と回避ができていません。
    ※現段階ではDB接続していないためセッション状態がSQLServerモードでの検証は行っていません。
     
    長々と書きましたが、この手のトラブルの回避策を教えていただけないでしょうか?

    CPU:2GB
    Memory:4GB 
    Windows2003ServerStandard
    ASP.NET2.0
    2007年5月25日 17:46

回答

  • 自己レスです。

    ※10カ月近くほったらかしでした。申し訳ないです。

     

    質問時と若干環境が変わり、sessionStateをDBステート<sessionState mode="SQLServer"に切り替えました。

    但しDBステートに変えても、同様のエラーが出ていました。

     

    試行錯誤の結果、多重ですが以下の対策を施しました。

    ①Boot.iniに/3GBスイッチを適用。

    ②巨大なDataTableはSessionオブジェクトに入れるのを止め、DB上に自前の該当DataTable用テーブルを作り、セッションと同じように、アクセス時にデータを読み込み(SELECT)、Page.Unload時にデータをテーブルに書き出す(BULK)仕組みを作成。

    ③IISのアプリケーションプールのメモリリサイクル量を仮想800MB、使用700MBを上限とした。

    ④IISのWebガーデンをCPU個分増やした。

    ⑤web.config(グローバル/ローカル共に)から不要なアセンブリを削除。

     

    導入理由と効果についてですが

    ①の対策

     メモリの使用上限をアップ。

     以前の2倍ぐらいのデータ量までOutOfMemoryExceptionは出なくなりました。

    ②の対策

     直接原因であるStringBuilder発のエラーを避けるための緊急処置。

     以前の4倍のデータ量ではOutOfMemoryExceptionで出なくなりました。(4倍以上は試していません)

     意外なことに処理速度も30%ぐらい向上しました。

     ※セッションを利用しないと同義ですが…

    ③の対策

     直接対策というよりメモリ確保量が多くなり、危険な状態のワーカープロセスをサクサク終了するためです。 

     OutOfMemoryExceptionの発生頻度が9/10~1/2ぐらいになりました。

    ④の対策

     危険な状態のワーカープロセスの利用頻度を下げられるのでは?と思い導入。

     OutOfMemoryExceptionの発生頻度が3/4~1/2ぐらいになりました。

    ⑤の対策

     一部のHPアセンブリが多いとOutOfMemoryExceptionが発生しやすいと書かれていたので導入。

     効果は不明です。

     

    印象的には②が最も効果的でした。

     

    上記の対策が効いたのか、ここ数カ月OutOfMemoryExceptionは発生していません。

     

    なお、.NETFramework自体にもOutOfMemoryExceptionが発生する不具合があったので、以下のパッチも導入予定です。

    ⑥.NETFramework2.0 SP1

     

    2008年3月13日 15:41