hnwの日記

PHPのcopy関数がファイルサイズ分のメモリを消費する件の対策


補足(2010/08/24 15:00):rename関数について言えば、同一ファイルシステム上であればrenameシステムコールを利用するのでこの問題は起こりません。さらに蛇足ですが、ファイルシステムをまたがってrename関数を利用するとコピーしてから削除することになり、アトミック性を保証できないため、障害の原因にならないかどうかの検討が必要だと思います。


AKIBA de: PHPのrename()関数はファイルシステム間で使うとメモリをバカ食いする」で指摘されている通り、PHPのcopy関数やファイルシステムをまたがってrename関数を使う場合に、PHPがファイルサイズと同じ大きさのメモリを消費してしまいます。環境によっては再現しないかもしれませんが、僕の手元のMacOSX 10.5+PHP5.3.3環境では再現しました。

<?php
// 「dd if=/dev/urandom of=1gb.dat bs=1m count=1024」でファイルを作ってから実行してください。
copy("./1gb.dat","./1gb.bak");

原因と対策

この原因はPHPの実装にあります。copy関数を実現しているコード部分を以下に示します。

続きを読む