PHPはリファレンスカウントGCを使っているというお話
バイト先でHyper Estraierを使った全文検索機能を実装する機会がありました。
そこで、EstraierPureライブラリを使って、PHPスクリプトを通じてHyper Estraierにテキストのインデックスを作成させるようにしたのですが、複数のテキストファイルをインデックス化する途中で下記PHPエラーが出てPHPプロセスが終了しました。
PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 22423 bytes) in /var/lib/Services/HyperEstraier/Utility.php on line 278
なんかメモリが足りなくなっとるらしい。
また、インデックス化に失敗したテキストファイルから実行再開すると、そのテキストのインデックス化に成功した後、別のテキストファイルをインデックス化する時に同様のエラーが出てプロセスが終了します。
以上の結果からメモリリークの疑いが強いのですが、EstraierPureは100%PHPコードなので、PHPのメモリ管理に原因がありそうです。
ということで、PHPのメモリ管理方法を調べてみたところ、リファレンスカウント方式のGCだと判明しました*1。今までTracing GC系だと思ってたよ・・・
現在、PHPのリファレンスカウントGCは循環参照しているオブジェクトは解放できません。おそらく、EstraierPureの中で循環参照があって、そのオブジェクトが解放されずにリークし、最終的にメモリが足りなくなるのでしょう。
PHP6からは、Pythonでも使われているCycle Collector*2が実装されるそうなので*3、今回の問題もPHP6を使えば解消します。
ってまだPHP6は正式リリースされてないし、今更PHP5から変えられるかーっていう状況。PHP5.3でもCycle Collectorが導入されるといいなあ。・・・結局リリース待ちなわけだけど。
*1:PHPカンファレンス2007 「PHPの今とこれから 2007」:http://www.php.gr.jp/seminar/20070901/data/phpcon070901a.ppt
*2:Cycle Collectorアルゴリズムの論文: http://www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf
*3:PHPカンファレンス2007 「PHPの今とこれから 2007」:http://www.php.gr.jp/seminar/20070901/data/phpcon070901a.ppt
tracの移行作業
少し前のことですが、tracの移行作業(subversionのリポジトリ移行も含む)を行いました。
今後、同じ作業をどこかでするかもしれませんので、忘れないようにメモ。
例として、
- trac-projというtracプロジェクト
- svnrepというsubversionリポジトリ
を別マシンに移行する場合を考えます。tracのDBはsqliteとします。
まず、移行元のマシンでtrac-projとsvnrepのバックアップを取ります。他ユーザのアクセスとバックアップが競合しないようにhotcopyコマンドを使ってロック+バックアップします。
$ trac-admin ~/trac/trac-proj hotcopy trac-backup $ tar cvfz trac-backup.tar.gz trac-backup $ svnadmin hotcopy ~/svn/svnrep svn-backup $ tar cvfz svn-backup.tar.gz svn-backup
ディレクトリ位置は適当です。自分の環境に合わせて変更すること。
移行先に両tar.gzファイルを持って行き、展開。なお、リポジトリの位置が移行元と違う場合、移行先でtrac-proj/conf/trac.iniの修正が必要。
例えば、以下のような感じ。
repository_dir = /home/user/svn/svnrep ↓ repository_dir = /var/svn/svnrep
移行先tracのバージョンが移行元より新しい場合、以下コマンドを使ってtracプロジェクトの更新をしておく。
$ trac-admin trac-proj upgrade
apacheの設定とかに関しては、以下リンク先を参照 (Trac月プロジェクト*1における移行作業の話だけど、十分役に立ちます)
http://sourceforge.jp/projects/traclight/wiki/Install
なお、apache2.2より、httpd.conf内の"AuthDigestFile"が"AuthUserFile"に変わったので注意すること。
XForwardingのやり方
ついでに、ssh XForwardingのやり方も調べました。
設定方法
例として、sshdが動いているRemoteマシンと、そこへssh接続するLocalマシンがあり、RemoteマシンでXクライアント(emacsとか)を起動し、LocalマシンのXサーバで表示する場合を考えます。
Remoteマシンのsshd_configを以下のように書き換えます
X11Forwarding no ↓ X11Forwarding yes
設定を有効にするため、sshdを再起動します。
# /etc/init.d/sshd restart
あとは、Localマシンから以下のように接続します
$ ssh -X user@remote.domain
sshでRemoteマシンに接続した後、以下のような出力があればXForwardingに成功しているはず。
$ echo $DISPLAY localhost:10.0 $ emacs #Localマシン上にemacsのウインドウが表示される
なお、ssh接続時に、~/.Xauthorityが生成されない場合、xauthプログラムが入ってない可能性がありますので、yum install xauthとかで入れて、接続しなおしてください。
やってみた感じ、通信データ量はかなり多いみたいですね。
回線が細いと、emacsの起動をするだけで数分かかります。
また、XForwardingの場合、nohupでXアプリを起動しても、sshコネクションを終了するとXアプリも終了してしまいます。
環境変数DISPLAYについて
環境変数DISPLAYは、":0.0"(通常)だったり、"localhost:10.0"(XForwarding)だったりしたんですが、値の意味が気になったので色々検索してみると、解説が見つかりました。
以下引用*2。
環境変数`DISPLAY'の書式は`HOST:DISPLAY.SCREEN'です。HOSTはXウィンドウシステムのサーバーマシンの名前、DISPLAYは同じマシンの別のサーバーと読者のサーバー(X端末)を区別するために任意に割り振られた番号、SCREENは稀にしか使いませんが1つのXサーバーで複数の端末画面を制御する場合に使います。ピリオドとSCREENは省いてかまいません。指定する場合、SCREENは普通はゼロです。
Bilingual Debuggerプロジェクト紹介(だけしとく・・・)
ひさびさ。
実はだいぶ前なんですが、Sourceforge.jpにプロジェクト立ち上げました。
http://sourceforge.jp/projects/bdbg
C/C++とRubyという2つの言語のデバッガ(gdbとrdb)を切り替えて使うことを可能にするツールをアップしてあります。
VC# 2003以降のデバッガに備わっている、C#とC/C++デバッガの切り替え機能を想像してもらえれば大体あってます。
詳しくはWikiに書いたマニュアルを見てください。
Fedora6でしか動作チェックしてないので、うまくコンパイルできないとかあれば、ブログコメントかSorceforgeのフォーラムにでも書いてくれれば対処します。
#返事が遅くても怒らないでくだせえ
バイト+就活+レポートのトリプル攻撃のため、このプロジェクトに割り当てる時間がないれす。
ブラウザ間のCSS解釈の違い
バイト先で、ブラウザ間のCSS解釈の違いでだいぶはまりました。
参考リンクを貼っとこう。
特に、バイト先ではまったのは以下、
ボックスの幅や高さを算出するときにパディングやボーダーのサイズを含めてしまう
ブラウザ間の差をバグと呼ぶかどうかは、バグの定義しだいなので微妙ですが・・・。
まあ、今回はどうでもいいですね。
オープンソースソフトウェアのHTML Help (chmファイル)
オープンソースソフトウェア(autoconf, gcc, perl等)のマニュアルをchm形式に変換してアップしてるサイト
http://htmlhelp.berlios.de/wiki/CHM_Books
chmだと、前方一致のキーワード検索ができるので、autoconfのマクロを調べる場合などにとても便利。
chmの作り方は以下のサイトが詳しかった。
http://www.keiyu.com/help/index.htm
HTMLのTitleタグから索引キーワードを自動的に作るスクリプトとかないかなあ。