• ベストアンサー

メモリリーク対策

トップページを開くたびに、SQLサーバへデータベースを参照し、内容を表示させる、というASPページを作成しましたが、メモリリークが度々起こります。プログラムを調査しましたが、解放していないロジックは見当たりませんでした。とりあえずの対応として、サーバ再起動を1/週で実施するようバッチを作成しました。 しかし、トップページには、 <META http-equiv="refresh" content="1800"> が記述してあり、 もしかしてこのrefreshが問題なのかと思って調べているのですがイマイチはっきりした回答がありません。 恐れいりますが、 refresh指定すると、メモリリークは必ず発生してしまうものなのでしょうか? どなたか教えていただけましたら幸いです。 その際、回避方法なども教えていただけましたら助かります。 以上、宜しくお願い致します。

  • goot
  • お礼率68% (13/19)

質問者が選んだベストアンサー

  • ベストアンサー
  • hisappy
  • ベストアンサー率46% (184/392)
回答No.3

ひとまず、「DBを使ったWebアプリケーション開発の全面経験者」 という広範囲での経験者です。 質問者さんのシステムで当てはまるかどうかは判りませんが、 質問文の範囲から聞き取れる「システムの悲鳴」から 原因を診察してみます。 [症状] refreshにより繰り返されるストレスの蓄積による慢性疲労。 現在は週1回のサーバ再起動によるストレス発散にて 擬似新入社員状態(?)となり勤務継続しているが、 一週間の連続勤務によって(再起動までの)約336回の ストレスに耐えるのがやっとのようである。 サーバの稼動状態にもよりますが、 週一回の再起動を基準に考えると、 現状のままでは、サーバの起動開始からプログラムがこけるまで 稼動状況が変わらなければ450回付近といった、 ほぼ似通った回数で毎回発生するものと思われます。 [原因と対策] まずは当該ASPスクリプトが常駐する、 もしくはそれに伴う「スクリプトの環境」が 常駐するような設定になっている事が前提となりますが、 メモリリークの原因は「DBコネクションの開放漏れ」 が考えられます。 想定される場所と内容 ・ASPの最初にDBと接続を行っている処理  (最後に対応するディスコネクトの処理が無い) この場合、refreshがかかるたびにコネクトするだけして ディスコネしていないので、結果コネクトするクチが 足りなくなってこける。 ・select句発行に伴うコネクト処理と開放。  (一度にオープンしたままにしようとするクエリが   多過ぎると発生。) この場合はこけるまでのrefresh回数が不定である場合に可能性大です。 抽出したデータを持つだけ持って突合処理をするだけやって、 最後のメモリ開放などの掃除の処理の際に いくつのクエリを保持していたのか管理している変数の値が 処理中におかしくなったなどの理由で 正しく掃除されていないために、掃除し忘れのクエリが残ったままとなります。 それが蓄積された結果、上記のDBコネクトと同様 クエリを発行するためのクチが足りなくなってこけることになります。 質問文で述べられている  ・ロジック自体におかしな部分は見当たらない。  ・しかし、しっかりコケルという症状は出る。  ・サーバの再起動で一応対処可能。 という3点から  ・システム環境(DB、ASP、ブラウザ(?))の   約束事の設定に忘れていることがある。 点で推測してみました。 時間と手間に余裕があるのならば、 発生条件(回数や件数や同時アクセス数や経過時間)を出来る限り特定して その条件がそろったときに、ロジックのどのような処理の部分が 悲鳴を上げているのか、「ロジックを一旦全部コメントにして」 順番にロジックを甦らせて条件と要因を特定するのが Web系統の開発の1つの手法だったりもします。 それでも「とことん突き詰めていった結果」、 実は「ソフトのバグだった」というオチもあります。 大規模なシステムであるほど「この点でおかしくなる」というのと 「そこで何が発生しうるか」をどれだけ思いつくのかが 意外と大切な開発現場だったりします。

goot
質問者

お礼

大変貴重なご意見ありがとうございます。 今は、おっしゃられた通り 時間と手間に余裕があるのならば、 発生条件(回数や件数や同時アクセス数や経過時間)を出来る限り特定して その条件がそろったときに、ロジックのどのような処理の部分が 悲鳴を上げているのか、「ロジックを一旦全部コメントにして」 順番にロジックを甦らせて条件と要因を特定するのが ということをしております。 サーバの監視ということで現在運用部署がログ収集やサーバ設定状況、メモリ状況などを監視しているところです。 その結果は、まだ聞かされていない(調査中段階なので)のですが、実は、ずっとエラーが起こっていない状態です。(すいません、結果を聞いてからご報告しようと思っていたのですが、遅すぎて待てないので御礼文を書かせて頂ます。) ひとまず、ロジック的にも問題なく、refresh指定にいたっては、今回の場合全く関係がないと思われますので、今しばらく状況監視を続けようと思います。 そのほか、いろんなパターンでの考えられる原因を探って頂きありがとうございました。今後、他のアプリ開発の時にも役立ちそうです。 ありがとうございました!

その他の回答 (2)

  • takkunnet
  • ベストアンサー率74% (32/43)
回答No.2

データベース内容の定期更新のページとのことですが、 1回あたりの表示にかかる時間はどのくらいなのでしょうか? また、たびたび起こるとのことですが、1回表示時、2回表示時のそれぞれのメモリ使用量は明らかに「2倍」近くになっているのでしょうか? 1回目でこけることは無いのでしょうか? SQLサーバではないので関係ないのかも知れませんが、以前、他社のDBを利用しているときにレコードセットの開放をしているにもかかわらずメモリが開放されていないっていう症状に悩まされました。 そのときはgootさんと同様メモリリークが多発したのを記憶しております。 そのときの解決方法としてはDBからのデータ取得を分断させて回避しました。 要は1つのレコードセットで取得するデータ量を減らしたのです。 ただ、gootさんの場合は30分という結構長めの再読み込みですからこれには該当しないかも知れませんね。。。

goot
質問者

お礼

回答ありがとうございます。 1回あたりには1秒以下で表示されます。 >そのときの解決方法としてはDBからのデータ取得を分断させて回避しました。 もともと、1回の取得でgetするデータは少ないのでやはり、refreshの問題ではないような気がします。 貴重なご意見ありがとうございました。

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.1

なぜ、メモリリークと分かったのですか? その方法を教えてください。 少なくとも、refresh指定でメモリリークする、なんて話は聞いたことが無いです。

goot
質問者

補足

回答ありがとうございます。 >なぜメモリリークとわかったのか IISログ(system32->logfiles)にメッセージが出ていました。(メモリ不足)メッセージが続き、最後サーバダウンしてしまいました。 また、 == 定期的にリフレッシュするときに、(同時に多数)CGIプログラムが読み込まれて、そのプログラムがメモリを正常に解放できないケースが発生するのではないかと。 == というほかの方からの意見をもらいまして、因果関係を調べていたのですが、はっきりわからず質問させて頂いた次第です。 宜しくお願い致します。

関連するQ&A

  • URL指定のないHTTP-EQUIV="Refresh"

    稀に以下の様なページが出る事があるのですが、 これはどういう原因で起こるのでしょうか? <HTML> <HEAD> <META HTTP-EQUIV="Refresh" CONTENT="0.1"> <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Expires" CONTENT="-1"> </HEAD> </HTML> 0.1秒毎にキャッシュ消しながらリフレッシュ、という意味だと思うのですが、サーバー攻撃みたいな事になっていて困っています。

  • Refreshの回数

    Aというページから<meta http-equiv="Refresh" content="*; url=******">を使ってBに飛ばしたものを再びAに戻したいのですが、AのRefreshの部分に何かを入れないとA~Bをループするだけになります。何か簡単な方法はないのでしょうか? 宜しくお願い致します。

  • <META HTTP-EQUIV='refresh' CONTENT='1;URL=★'>のこと

    <META HTTP-EQUIV='refresh' CONTENT='1;URL=http://www.yahoo.co.jp/'> このようにページを飛ばしたいときで、現在のページがある場所がフレーム内のときに、 target=_topと指定したりできるものでしょうか。

    • ベストアンサー
    • HTML
  • 携帯サイトで自動ジャンプの方法

    携帯サイトを作成しています。 あるページにアクセスすると自動的に指定したURLへ飛ばす方法 を探しています。 イロイロと調べた結果、 <meta http-equiv="Refresh" content="1; URL=http://~"> <META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://~"> 上記2つのやり方があることが分かりましたが、携帯サイトでは使えないようでした。 携帯サイト(3キャリア)で有効な方法があれば教えてください。 よろしくお願いします。

  • メモリリークを調べています。

    メモリリークを調べています。 MFC(VC2005)です。 MFC拡張DLLで作成したアプリケーションにメモリリークがないかを調査し始めたのですが、VisualStudioでデバッグでは 「Detected memory leaks!」は出ません。 パフォーマンスモニタで、このDLLを静的リンクしたEXEのPrivateByteを約90時間監視すると、2回だけ大きな上昇(といっても数10KB)が見られました。 上昇するまでは横ばいですが、この横ばいの時間が2回とも異なります。 これはメモリリークと言えるのでしょうか? ちなみに、このDLLの調査対象機能は画像描画機能で、定期的にメモリ確保→メモリ解放を繰り返します。 メモリリークでないとしたら、どう結論付けたら良いでしょうか? 解決方法はありますか? 私としてはフラグメンテーションを疑っています。

  • WEBページのリフレッシュについて

    <META HTTP-EQUIV="refresh" CONTENT="60;URL=XXXXX.htm"> をつかってWEBページをリフレッシュしています。 ところが途中から動かなくなったり OSによっては最初から動かない場合があります。 これって対策はないのでしょうか。 ブラウザはIE5とIE6でテストしています。

  • 条件によってmeta http-equiv="refresh"で表示するページを変更する方法

    プログラミング初心者なのですが質問させて頂きます。 ページ1で値を入力し、ページ2へ送ったとして、 入力された値が1の場合index1.phpへ、 入力された値が2の場合index2.phpへ自動的に移動するプログラムを作成しようとしています。 この場合if文を使って if(num == 1){ <meta http-equiv="refresh" content="1;URL=index1.php"> } elseif(num == 2){ <meta http-equiv="refresh" content="1;URL=index2.php"> } このように作ろうとしたのですが、 <?php ~ ?>の中ではmeta http-equiv="refresh"が動かず、 <?php ~ ?>の外ではif文が動きません。 この場合どうすればいいのかわかりません…。 どなたか助言をお願い致します。

    • ベストアンサー
    • PHP
  • 突然リフレッシュがLAN内で使えなくなりました。

    <meta http-equiv="refresh" content="0;url=***">というページをいくつか使用して今現在も使っているのですが、5日前位にリフレッシュページのとび先を変更して更新したら変更が更新されず、いつまでも以前のとび先になってしまいます。 それはLAN内に限られたもののようで外部から接続してみてみるときちんと変更が効いています。 履歴のクリアやファイルの削除もしています。 クライアントPCの設定等変更はありません。 サーバでなにかすればこういった現象が起こったりするのでしょうか?

    • ベストアンサー
    • HTML
  • リロードについて

    お世話になっております。 メタタグでリロードする時に、 <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Refresh" content="1"> と書けば1秒おきにリロードされるんですけど、そのページを開いた瞬間に一回だけリロードされるようにしたいです。 一回のみリロードされる方法をよろしくお願いいたします!

  • metaのcontentを使ってフォームの値をPOSTで渡す方法

    A.html <meta http-equiv="refresh" content="10; url="A.html"> とメタタグ?を使用して10秒後に同じページをリロードして読み込みます。 その時にGETではなくPOSTを使ってフォームの値を渡したいのですがうまくいきません。 metaを使用してPOSTで送ることは無理なのでしょうか? もしmetaを使用して無理なら、ASPを使用してリロードをすることはできるのでしょうか? どなたか酔い方法をご存知でしたら教えてください。 よろしくお願いします。

    • ベストアンサー
    • HTML

専門家に質問してみよう