PHPのfread関数は、第2引数で指定した分だけメモリを消費する

PHPのfread関数は、第2引数で指定した大きさのバッファを確保してそのまま返すらしい。

実際に読み込んだバイト数が小さかったとしても、返された値をそのまま配列に入れてると、すぐにメモリが足りなくなる。

$ echo hoge | php -r '
    $a = memory_get_usage();
    $b = fread(STDIN, 1024 * 1024);
    $c = memory_get_usage();
    printf("%s\n", number_format($c - $a));'
1,057,288
$ echo hoge | php -r '
    $a = memory_get_usage();
    $b = fread(STDIN, 2048 * 2048);
    $c = memory_get_usage();
    printf("%s\n", number_format($c - $a));'
4,203,016

これならfreadで使用したバッファがすぐに開放される。

$ echo hoge | php -r '
    $a = memory_get_usage();
    $b = "".fread(STDIN, 2048 * 2048);
    $c = memory_get_usage();
    printf("%s\n", number_format($c - $a));'
8,712

利用したPHPのバージョン

$ php --version
PHP 5.3.10-1ubuntu3.1 with Suhosin-Patch (cli) (built: May  4 2012 02:20:36)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies