こんばんは。いきなりですが、質問があります。
CGIで動的にHTMLを作成したのですが
あるページに多数ユーザが接続しようとすると
フリーズしてしまいます。
調査してみたところ、Perlが実行時にメモリを
多く確保しているためのようです。
また、そのページではフレームを使用しているため、
1ユーザに複数プロセスが起動されるので、
それもメモリ不足の原因ではと思っています。
メモリの使用量を下げようとしているのですが、
知識足らずなため、思うようにいきません。
どなたか良い方法をご存知でしたら、
教えていただきたいのですが。
よろしくお願いします。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
あ、今見返していたらバグが。
すみません。sub my_function {
my ($bigbigbig_data_ref) = @_;
for my $data (@$bigbigbig_data) {
は
for my $data (@$bigbigbig_data_ref) {
ですね。
なんか読み返すと、tayahaさんを初心者と決めつけてるようなところ
があって…お気を悪くしたらごめんなさい。
もしご存知無かったら、ということなのですが…そうそう、
サブルーチンの返り値となる変数もmyして結構ですよ。
sub my_func {
my $abc;
....
return $abc;
}
my_funcを呼び出した側で$abcを使ってる場合はmy_funcを抜けても
$abcは掃除されることはありません。(my_funcを呼び出した関数が
終わったときに掃除されます)
要するに、基本的になんでもmyを付けましょう、ということです。
perl -w オプションとuse strict;を使いましょう。
グローバル変数についても
use vars qw(@MY_GLOBAL_ARRAY);
として、明示的にグローバルとして使う!と宣言してないものがあれば
警告してくれます。
No.2
- 回答日時:
いくつかチェックポイントはあると思います。
まず、そのCGIは本当に必要か。普段は静的なHTMLページを表示して、
情報が更新されたときだけそのHTMLページを更新するようなことです。
掲示板でも最近多いですよね。ただ見るときだけのときは「~xxx.cgi」
ではなくて「~/xxx.html」を閲覧するようなもの。それで済むなら
そうしましょう。
次に、やはりプログラムのシェイプアップでしょうか。これには、さまざま
な場合があるのでひとくちにご説明するのは無理ですが、よく見かける
ものを念頭にちょっとだけポイントを書いてみます。
・ファイルの中身を @data = <FILE> といった調子で丸ごと読みこんで
いる個所があったら、
while (<FILE>) {
}
の形に直しましょう。確保されるメモリが1行分で済むようになります。
・グローバル変数を多く使ってるならなるべく局所変数にしましょう。
$abcがforループの中でしか参照されないのだったら、
my $abc;
for $abc (@array) {
$abc = ....
}
よりも
for $abc (@array) {
my $abc = ....
}
のほうが、いいということです。ループを抜けるときに掃除されますから。
サブルーチンでも同様です。サブルーチンの中だけ使うのならそこで
my。
・サブルーチンを呼び出すとき、配列やハッシュを引数として受け渡しする
かわりにリファレンスを渡す。
&my_function(@bigbigbig_data);
....
sub my_function {
my (@bigbigbig_data) = @_;
for my $data (@bigbigbig_data) {
.....
}
よりも、
&my_function(\@bigbigbig_data);
....
sub my_function {
my ($bigbigbig_data_ref) = @_;
for my $data (@$bigbigbig_data) {
.....
}
の方がベターということです。Perlのサブルーチン呼び出しはコピーに
なります。上記の例であれば@bigbigbig_dataが丸ごとコピーされることに
なります。ここでリファレンスを渡すようにすると、リファレンスそのもの
だけがコピーされ、両方とも同じものを指す、すなわち余分なメモリを食わなく
なるわけです。まあこれは程度問題で、$abc = 123とかの小さいデータを
渡すときにもムキになってリファレンスにする必要はありませんが。
他にも、細かいテクニックはいろいろあります。(ラクダ本の後ろの
ほうにあるメモリを節約するテクニックについて解説した章も参考に
してください)
以上をやってもキツい場合、ちょっと細かいテクニックになりますが、
セマフォを使って制限できる場合もありますね。
乱暴に言えば、flockを一度に単数のアクセスに制限するものとするなら
一度に複数のアクセスを許すロックみたいなものです。
詳しくはperldoc -f semctlやperldoc IPC::Semaphoreをご覧ください。
OSによっては使えない場合もあります。
まあ、自前でロックファイルを作るような形で、セマフォにあたるものを
作成する方法もできなくはないでしょう。
20個なら20個のアクセスまでを許し、それを越えていたら20以下になるまで
スリープする、あるいはエラーページを吐いて終わるような仕掛けを。
あと、大胆に、CGIのいくつかを他のサーバにおいてそっちで起動するように
する方法もあるでしょう。
------
たしかにサーバ側でコネクションを絞る手もありますね。例えば
ApacheだとMaxClientsやMaxSpareServersで設定することになるんでしょうか。
でも1.3ぐらいだと、全体でのDirectoryごとに細かくコネクション数を
設定できなかったような記憶があります。CGI以外の静的ページについても
制限することになりますね。まあ、背に腹は代えられないってことですかね。
それとも最近のバージョンだと違うのかな?また別のサーバなら話はまったく
異なるでしょうね。
No.1
- 回答日時:
一般的にはwebサーバがわでマックスのコネクション数を設定できるので
それで制御しましょう。
もしwebサーバをいじれないのなら、perlプロセスの数をpsコマンドで数えて
多かったら「不可が高いです」だけだして即終了してしばらくまってもらうとか
そうすれば最悪の事態は確率的に回避できます。
でも、一番懸命なのはスクリプトをもう一度みなおして無駄に変数を
つかってないか確認してみましょう。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
RFC822形式の日付を生成するサ...
-
VBのReturnの使い方
-
VBA for i=1 to lastrow
-
UWSCの終了の仕方
-
再帰関数のインライン展開
-
画面を強制的に再描画させる方法
-
vb.netからエクセル関数書き込み
-
perl 初等プログラミングについて
-
Escキーを押すと、中断する時と...
-
DOSコマンドのループ内のTIMEコ...
-
ループフリー
-
文字列の分割について
-
Perlは戻り値で、ハッシュや配...
-
範囲指定したセルを1つずつ飛...
-
組み合わせについての質問です...
-
jQuery を使用した経過時間の表...
-
イベントの発生を待つ
-
Excel VBA ユーザーフォームの...
-
配列やハッシュで中身が同じか...
-
VBAのautofilter、criteriaの配...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBのReturnの使い方
-
ExcelVBAでのデータ型変換、も...
-
Perl・DBIでの汎用selectサブル...
-
関数の戻り値に配列は設定できる?
-
サブルーチン(共通の処理)の...
-
RFC822形式の日付を生成するサ...
-
CGIのサブルーチンの呼び出...
-
COBOLの日付操作
-
Perlのmyのサブルーチンの内外...
-
スカラー変数をチェック
-
流れ図・・・
-
UWSCの終了の仕方
-
画面を強制的に再描画させる方法
-
VBAで3秒だけ時間を止めたい
-
Escキーを押すと、中断する時と...
-
DoEventsが必要な理由について
-
VBAでの一時停止と再開の方法
-
DOSコマンドのループ内のTIMEコ...
-
範囲指定したセルを1つずつ飛...
-
GIFアニメをループさせたくない
おすすめ情報