(タイトル変更済み)PsySHには変数をunsetしてもリソースが解放されないバグがある


PHPマニュアルのリソースの項目を読むとこんな記述があります。

PHP 4 の Zend エンジンに導入されたリファレンスカウンティングシステムのおかげで、 あるリソースがもう参照されなくなった場合に (Java と全く同様に)、 そのリソースは自動的に削除されます。この場合、このリソースが作成した 全てのリソースは、ガベージコレクタにより開放されます。 このため、free_result 関数を用いて手動でメモリを開放する必要が生じるのはまれです。

ところがですね…手元のOSXで以下のコードで無限ループさせてファイルを手動で削除しようとしたところ、動作に差がありました。
fcloseする
$fp = fopen('test.txt', 'a');
fclose($fp);
while (true) { }
unsetする
$fp = fopen('test.txt', 'a');
unset($fp);
while (true) { }
fcloseの場合は正常に削除出来ましたが、unsetの場合は「使用中」となっていて削除出来ませんでした。スクリプトを強制終了すれば解放されましたが、終了時までは解放されないようです。
  • flock(\$fp, LOCK_UN)でのロック解放はもちろん、fclose($fp)もちゃんと書こう
  • 面倒だったら出来るだけSplFileObject使おう

訂正します。まさかこんなところで差がでるとは思っていなかったのですが、実際にwhileループではなく、psysh上で確認していました。

実際に最初記事に書いたとおりに試してみると、@hnwさんの仰る通り正しい挙動になりました。PsySHのシンボルテーブル管理方法に問題があると見たほうがいいかもしれません。

思い込みで誤った記事を書いてしまったことをお詫びします。お騒がせしました。