• ベストアンサー

PHP4 メモリ使用量について

PHP4+PostgreSQLでプログラムを作成しています。 メモリ使用量の検証として、selectで全件検索をかけて、pg_fetch_resultを用いて順次ブラウザに出力し、都度memory_get_usageでメモリ使用量を確認したところ、単にHTMLを出力するだけでメモリの使用量が増え続けていたのですが、これは仕方がないことなのでしょうか。 例えば何か設定で回避することが可能であったりしますか?

noname#65806
noname#65806
  • PHP
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
回答No.3

どのくらいの使用量なのかわかりませんが、そんな巨大なHTMLを出力したら、見る方も大変なのでは? mod_phpでApacheにContent-Lengthヘッダを出させていれば、 出力前にデータをため込んで、PHPからの出力が終了したらそのサイズを確認し、 Content-Lengthヘッダとして出力するので、バッファのため込みは避けられないと思います。(ため込まないとファイルサイズがわからない) あらかじめファイルサイズがわかれば自分でContent-Lengthヘッダを出力すればよいですが、まず無理ですので、 header('Transfer-Encoding', 'chunked'); を使って見てはいかがでしょうか。 それでも使用メモリが減らないようなら、適当なタイミングでechoした内容(バッファ)を、クライアントに送信する処理が必要です。 Perlではflush()ですが、すみませんがPHPではわかりません。 頻繁にflushすると、パフォーマンスが落ちます。 CGI版PHP(mod_cgi)では、特に気にしなくてもTransfer-Encodingを使い、最適なタイミングでflushしていると思います。 *出力バッファがらみです。 一案として。 昔はContent-Transfer: chunkedに対応していないブラウザが多かったようですが、今は大丈夫だと思います。 Ajaxでは、iCab等、一部のブラウザでデータが取得できないかもしれませんが詳しく調べていません。(iCabはContent-Type: multipart/*を取得できませんので、それが原因かも知れません) 携帯電話ではContent-Length必須、Content-Transfer: chunked未対応です。 CGI関連はCGIカテゴリーで質問するともっと良い回答が得られるかもです。 ご参考まで。

noname#65806
質問者

お礼

ご丁寧なご回答ありがとうございます。 データを全件表示したいという要望があり試してみた次第です。 Transfer-Encodingをchunkedとしても動作は変わりませんでしたが、一定のタイミングでバッファをフラッシュしながら出力したところ、メモリ使用量が増え続けることなく全件の出力ができました。 また、その他の情報も大変参考になりました。

その他の回答 (2)

  • wp_
  • ベストアンサー率54% (132/242)
回答No.2

単純にhttpのバッファに溜まりこんでいるだけじゃないですかね。 while($row = pg_fetch_assoc($pid)) {  echo $row['data'] . "<br />\n";  echo memory_get_usage();  echo "<br />\n"; } といった感じだと増え続けるのは道理かなぁとも思います。 巨大データをhttpで送信というのを当方はやったことないので分かりませんが、 対策としてはsocketを明示的に開き、こねくり回せばメモリ使用量も抑えられるのではという気がします。 // タイムアウトや遅延の設計も行わねばならないのでかなり面倒な気がしますが もしくはHTTPのバッファをオンメモリでない方法で独自に管理とか。

noname#65806
質問者

お礼

早速のご回答ありがとうございます。 出力件数を制御してしまえば問題にならないことだったのですが、どうしても気になって質問してしまいました。 httpのバッファの問題とのことで、メモリ使用量が増えるのはやはり仕方がないということと理解しました。 *バッファを独自に管理することについては知識がありませんので調べてみます。

  • SAYKA
  • ベストアンサー率34% (944/2776)
回答No.1

それ、webアプリとしてapacheか何か経由で動かしてるの? だとすればPHPをcliで駆動すれば増え続けるのは押さえられるんじゃないかな。 モジュールとしての駆動とcli駆動がどう違うのか調べると言ってる意味が判ると思うよ

noname#65806
質問者

お礼

早速のご回答ありがとうございます。 PHPはapacheでCGIとして動かしいます。 CLIについては全く知識不足なのでこれから調べてみます。

関連するQ&A

  • PostgreSQLのメモリ使用量について

    お世話になります。 漠然とした質問になってしまうのですが、 postgresのメモリ使用量が増加し続け、 最終的にメモリ不足になる現象で困っております。 もし、PostgreSQLのチューニングで解消できるようでしたら ご教示頂けないでしょうか? 詳細(ざっくりですが、、、)は、 周期的にSELECTを実施しているプロセスがあるのですが、 psで監視すると、postgresのメモリ使用量が、 少しずつですが増加し続け SELECTをやめると増加は止まるのですが、 増えたままで減りません。 (試験的にSLEEPしてSELECTを止めた状態を作成) ちなみにSELECTしているプロセス(C言語)自体は メモリリークしておりません。。。 漠然としてて申し訳ございませんが お知恵をお借りできるとうれしいです。

  • php>postgresから得たデータを配列変数に

    PostgreSQL Ver13.7-2 php Ver7.2.24 htmlでphpを動かしながらPostgreSQLのデータをやりとしています。 pg_fetch_resutlで得たデータを配列変数に代入したいのですが、そんな関数はないでしょうか? イメージは以下の通りです。 $ma="select * from tb where 日付='2022-11-08'"; $mb=pg_qury($db,$ma); $h[]=pg_fetch_result($mb,*,1)   *はすべての列です。 仮に$mbの中に5つデータがあれば、$h[]にはゼロから4まで値が代入できればありがたいのですが。 以上、よろしくお願い致します。

    • 締切済み
    • PHP
  • PHPとPostgreSQL接続 (スキーマ)

    いつもお世話になっております。 現在、PHP(5.3.1)とPostgreSQL(9.2)で開発をしております。 エラーが発生しており大変困っております。 こちらが発生するエラーです。 Warning: pg_exec() [function.pg-exec]: Query failed: ERROR: schema スキーマが見つからないとのことです。 そして、以下がコードとなります。 <?php // PostgreSQL Connect if (!($cn = pg_connect("host=*** port=*** user=*** password=*** dbname=***"))) { die; } // PostgreSQL Select $sql = "select * from t_test.na1"; if (!($rs = pg_exec($sql))) { die; } // PostgreSQL Get Records $ct = pg_numrows($rs); for ($i = 0; $i < $ct; $i++) { $item = pg_fetch_array($rs, $i); $txt = "${item[1]}"; } // PostgreSQL Disconnect pg_close($cn); ?> 現在のデータベースのスキーマについてですが「na1」と「public」の2つが存在しています。 試しに、na1とpublicのテーブルをまったく同じにして SQLの部分を「select * from t_test」に変更すると「public」側のテーブルが覗けます。 しかし、SQLの部分を「select * from t_test.na1」に変更すると「スキーマが見つかりません」 というエラーが発生してしまいます。 スキーマがあるにもかかわらずこのエラーがでてしまうため原因が分からず困っております。 もしお分かりになる方いらっしゃいましたら、教えていただければと思います。 何卒よろしくお願いします。

    • ベストアンサー
    • PHP
  • pg_exec()、pg_result()は、使わない方が良いのか?

    去年の7月から、PHPを使っています。 そこで、初めて買った本の中で、pg_exec()、pg_result()を使ってPostgreSQLを使うサンプルプログラムが載っていました。 それを使って、webソースをくんできたのですが、ふと技術評論社のPHPのポケットリファレンスなどを見たら、pg_exec()、pg_result()が載っていません。(汗) googleなどで検索すると、また使っているようですが、将来性を考えると、pg_query()、pg_fetch_xxxx()などにソースを直しておいた方が良いのでしょうか? また、pg_fetch_xxx()の中で、pg_fetch_objectが、良いのでしょうか?

    • ベストアンサー
    • PHP
  • PostgreSQLからSQLiteへの移行について

    次のPostgreSQL用PHP関数と同機能のSQLite用PHP関数もしくは、SQLite用PHP関数の組み合わせを教えてください。 pg_fetch_result pg_affected_rows pg_result_seek

    • 締切済み
    • PHP
  • postgreSQL + PHPの連携

    現在postgreSQLとPHPを使い、 勉強を兼ねスクリプトを組んでいます。 が、早速つまづいてしまいました。。 [ID][名前][年齢]の3つのカラムがあります。 そこからIDが「10」の行を取得したいのですが、 どのように書けばよいのでしょうか? $sql = "SELECT * FROM TAB where(ID = 10)"; $rs = pg_query($cn, $sql); $row = pg_fetch_array($rs); echo "$row[ID]、$row[名前]、$row[年齢]"; 願わくば、と上のように書いたのですが、 「、、」と表示されるだけで…。 ご教示、お願いいたします。

    • ベストアンサー
    • PHP
  • メモリ使用量のログを取れるソフトありますか?

    サーバーのメモリやCPU使用量のログをある程度の期間とって、リストやグラフ等へ出力できるフリーソフトはないでしょうか?

  • PHPでtableタグのオプションを指定する方法

    教えてください PHPにて //表示するデータを作成 if($rows){ while($row = pg_fetch_array($result)) { $tempHtml .= "<table cellspacing="1" cellpadding="1" border="1"><tr>"; と書くと "でエラーがでてしまいますが エラーを回避してtableタグのオプションを指定する方法を 教えてください。

    • ベストアンサー
    • PHP
  • phpでデータリスト作成

    php+PostgreSQLでデータのリスト作成をしています。 DB内にあるデータを条件に合うデータを30件ずつ表示させ、ページ切替をしています。 10ページあると、ページ切替のリンクが、 1~10まで全て表示されます。 これを5ページ目まで+次ページ 前ページ 6 7 8 9 10 が表示 どのようにすればよいでしょうか? よろしくお願い致します。 現時点でのソースです。 **************************************************DB接続後 $sql = "select count(*) from entry_user"; $result = pg_query($sql) or die("Failed to execute SQL\n"); $row = pg_fetch_result($result,0,0); $ln = 30; if ($row%$ln == 0){  //表示する件数(MAX) $pn = floor($row / $ln); } else{ $pn = floor($row / $ln)+1;  } pg_free_result($result); $data = "entry_id,entry_time,company,dept,sei,mei,post1,post2,pref,address2,address3,email,entry_flag"; $sort_key = "entry_id"; //ソート対象フィールド $sort ="desc"; //ソート desc:降順 $sql1 = "select $data from entry_user order by $sort_key $sort limit $ln offset " . ($pnn-1)*$ln ; //SELECT文 $result1 = pg_query($sql1) or die("Failed to execute SQL\n"); $row1 = pg_num_rows($result1); for ($i = 0; $i < $row1; $i++){ $table[$i] = pg_fetch_row($result1,$i); } 一覧表示後(省略) //ここからページ切替作成 for ($n = 1;$n<$pn+1;$n++){ if($pn != 1){ if($n != $pnn){ print(" <a href=list01.php?pnn=" . $n . ">"); print($n . "</a> \n"); } else{ // ページ数が、現在表示しているページと同じで有ればリンクなし print($n . " \n"); }} else{ print("1\n"); }}

    • ベストアンサー
    • PHP
  • PHPロジックで・・・

    PHP4をHTMLに埋め込むロジックを書いてます。 DBはpostgresqlです。 <? print("<SELECT NAME=sendgroup>"); print("<option value=name>グループ一覧"); for($i = 0; $i < row; $i++){ $str = pg_result($res,$i,0); print("<option value=$str>$str"); } print("</SELECT>"); ?> DBから取り込んだデータをrow(行数)分まわして HTMLのセレクトオプション表示をしたいのですが 表れません。$strにDBから取り込んだデータが 入ってます。 普通にprint($str)データの値はちゃんととれています。 HTMLのselect文でなにか規約があるのでしょうか?

    • 締切済み
    • PHP

専門家に質問してみよう