Composerでメモリエラーが発生したときの対処方法【詳細解説】

こんにちは、ヱビス(@evisu0414)です。

先日、ローカル環境のComposerのアップデートを試みたときに、普段ほとんど素直にアップデートが終わるにも関わらず、エラーの嵐に見舞われました。

私が辿った失敗と合わせて、対応方法をご紹介していきます。

Composerでアップデート・インストールができない

Composerを使ったパッケージのアップロード・インストールを行った際に下記のようなエラーが表示されました。

$ composer update

PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/RuleSetGenerator.php on line 126

Composerが処理しているPHP側で「メモリが足りない」というエラーが発生しました。

人によっては「1073741824 bytes」の部分が異なるとは思います。

PHPのメモリを確認する

とりあえず、メモリが足りないということなので、現状のPHPに割り当てられているメモリの値を確認します。

$ php -r 'phpinfo();' | grep memory_limit

分かりやす方法として、「phpinfo」関数を実行するプログラムファイルを作成して、「memory_limit」項目を確認するという方法が考えられます。

ですが、結構手間なのでコンソール上で、同じことをするために上記のようなコマンドを利用します。

「php」は、PHPプログラムの実行コマンドですが、通常「<?php ?>」が必要になります。
PHPコマンドのオプションで「 -r 」というのがあり、これを付けることで「<?php ?>」がなくても、コンソールでPHPプログラムを実行することができるようになります。

そして、PHPで実行するソースを「’(シングルクォーテーション)」または「”(ダブルクォーテーション)」で囲みます。

今回は「phpinof()」を実行します。

次に「|(パイプ)」を使ってもう1つのコマンドをつなげます。

つなげるコマンドは、文字列検索を行う「grep」コマンドです。

「phpinfo()」を素直に実行すると大量の結果が、コマンドライン上に表示されて目的の情報を探すのに、非常に手間がかかってしまいます。

そこで、「grep」コマンドを使い知りたい項目のみを抽出します。

見たい項目は、メモリの最大値を管理している「memory_limit」となります。

実行した結果が下記になります。

memory_limit => 128M => 128M

PHPの初期設定のままです。

PHPのメモリ量を上げる

次に、PHPのメモリ量を上げてみます。

PHPの設定は「php.ini」で管理されていますので、「php.ini」ファイルを変更します。

$ sudo -s vi /etc/php.ini

ファイルを開けると「memory_limit」の項目があるので、探してみます。

memory_limit = 128M

この値を私の場合は「2G」に変更します。
「256M」や「512M」で試してみても良かったのですが、私の場合は明らかに足りないのが分かっていましたので、非常識なぐらいにあげてみましたw

変更後、Webサーバーを再起動して反映します。

私の場合は、「Apache」ですので、下記のコマンドを実行します。

$ sudo -s systemctl restart httpd

再起動が終れば、再度PHPのメモリが変わったのかを確認します。

$ php -r 'phpinfo();' | grep memory_limit
memory_limit => 2G => 2G

問題なく、「memory_limit」の値が変わっています。

まだ、Composerをアップデート・インストールできない

PHPのメモリも上げて、これで問題ないだろうと再度「composer update」を実行したところ、下記のようなエラーが表示されました。

The following exception is caused by a lack of memory or swap, or not having swap configured
Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details
                                           
  [ErrorException]                                   
  proc_open(): fork failed - Cannot allocate memory  

今度は、Composer側の例外処理としてエラーが表示されました。

内容としては「メモリまたはスワップが不足しているか、スワップが設定されていない」という内容です。

メモリは上がっていますので、原因としては「スワップ」が足りていないか、設定されていないというのが、原因のようです。

「スワップファイル」を作って回避する

スワップファイルを用意して、メモリのオーバーに対応します。

スワップファイルを作成する方法は下記の、「dd」コマンドを実行します。

$ sudo -s /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024

「if」オプションで、入力ファイルのを指定します。

「of」オプションで、出力ファイルを指定します。

「bs」オプションで、一度に「1M」バイトのブロックを書き込んでいきます。

それを「1024」回おこなうので、書き込むデータ量は「1G」となります。

これで「swap.1」というスワップファイルが作成できました。

続いて、作成したスワップファイルを、スワップ領域に設置して、有効化します。

$ sudo -s /sbin/mkswap /var/swap.1
$ sudo -s /sbin/swapon /var/swap.1

これで「スワップ」の設定ができましたので、再度Composerを実行してみましょう。

たぶん、成功したのではないでしょうか?

まとめ

Composerで、メモリ不足を起因とする問題はいろいろな環境で遭遇する可能性があります。

対処方法をいくつか持っておくことで、スムーズな解決ができるかと思います。