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が導入されるといいなあ。・・・結局リリース待ちなわけだけど。

tracの移行作業

少し前のことですが、tracの移行作業(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"に変わったので注意すること。

*1:Windows上にTracに必要なパッケージ(trac, apache, subversion等)をまとめて入れるソフトウェアの開発プロジェクト

XForwardingのやり方

ついでに、ssh XForwardingのやり方も調べました。

設定方法

例として、sshdが動いているRemoteマシンと、そこへssh接続するLocalマシンがあり、RemoteマシンでXクライアント(emacsとか)を起動し、LocalマシンのXサーバで表示する場合を考えます。

Remoteマシンのsshd_configを以下のように書き換えます

X11Forwarding noX11Forwarding 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アプリも終了してしまいます。

おそらく、sshコネクション終了時にRemoteマシン上に作られた擬似Xサーバも終了してしまうからでしょう*1

環境変数DISPLAYについて

環境変数DISPLAYは、":0.0"(通常)だったり、"localhost:10.0"(XForwarding)だったりしたんですが、値の意味が気になったので色々検索してみると、解説が見つかりました。

以下引用*2

環境変数`DISPLAY'の書式は`HOST:DISPLAY.SCREEN'です。HOSTはXウィンドウシステムのサーバーマシンの名前、DISPLAYは同じマシンの別のサーバーと読者のサーバー(X端末)を区別するために任意に割り振られた番号、SCREENは稀にしか使いませんが1つのXサーバーで複数の端末画面を制御する場合に使います。ピリオドとSCREENは省いてかまいません。指定する場合、SCREENは普通はゼロです。

Xアプリをssh越しで起動する

バイトの関係で、Xアプリを、外部からデーモンとして起動する必要がありました。
やり方を探してみたところ、ssh接続先で以下のコマンド列をうてばOKでした*1

$ export DISPLAY=:0.0
$ nohup x_program &
$ exit

ようは、ssh接続先のXサーバとXアプリ(Xクライアント)を繋げるように環境変数を設定したうえで、Xアプリを起動すれば良い。

当然、ssh接続先でXサーバが動いていないとだめです。

Bilingual Debuggerプロジェクト紹介(だけしとく・・・)

ひさびさ。

実はだいぶ前なんですが、Sourceforge.jpにプロジェクト立ち上げました。
http://sourceforge.jp/projects/bdbg

C/C++Rubyという2つの言語のデバッガ(gdbrdb)を切り替えて使うことを可能にするツールをアップしてあります。

VC# 2003以降のデバッガに備わっている、C#C/C++デバッガの切り替え機能を想像してもらえれば大体あってます。

詳しくはWikiに書いたマニュアルを見てください。

Fedora6でしか動作チェックしてないので、うまくコンパイルできないとかあれば、ブログコメントかSorceforgeのフォーラムにでも書いてくれれば対処します。

#返事が遅くても怒らないでくだせえ

バイト+就活+レポートのトリプル攻撃のため、このプロジェクトに割り当てる時間がないれす。

ブラウザ間のCSS解釈の違い

バイト先で、ブラウザ間のCSS解釈の違いでだいぶはまりました。
参考リンクを貼っとこう。

WinIEのバグリスト

特に、バイト先ではまったのは以下、
ボックスの幅や高さを算出するときにパディングやボーダーのサイズを含めてしまう

ブラウザ間の差をバグと呼ぶかどうかは、バグの定義しだいなので微妙ですが・・・。
まあ、今回はどうでもいいですね。

オープンソースソフトウェアの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タグから索引キーワードを自動的に作るスクリプトとかないかなあ。