メモリが足りないのでSwapファイルを作ってライブラリをインストールする

## メモリが足りない...

検証用にAWSでLinuxインスタンス(t2.micro, memory=1GB)上で、PHPのライブラリをインストールしようとしたら...

```
composer require predis/predis
```

えっ、メモリが足りない...。いわゆるOOM(Out of memory)エラーです。

```出力.
 Using version ^1.1 for predis/predis
 ./composer.json has been updated
 Loading composer repositories with package information
 Updating dependencies (including require-dev)
 
 mmap() failed: [12] Cannot allocate memory
 
 mmap() failed: [12] Cannot allocate memory
 
 mmap() failed: [12] Cannot allocate memory
 PHP Fatal error:  Out of memory (allocated 680185856) (tried to allocate 14952775 bytes) in phar:///usr/local/bin/composer/src/Composer/Util/RemoteFilesystem.php on line 451
 
 Fatal error: Out of memory (allocated 680185856) (tried to allocate 14952775 bytes) in phar:///usr/local/bin/composer/src/Composer/Util/RemoteFilesystem.php on line 451
```

インスタンスのサイズを大きくすれば解決するのだろうが、面倒やコストもかかる場合もある。

### 追記 (2021/03/01)
以下を試す前に、例えば composer であれば、設定ファイルを見直して、物理的にメモリが足りていないのではなく、設定として `memory_limit` などのパラメータで制限されていないか確認してください。


## Swapファイル、ddコマンドとは
### Swap ファイルとは
> スワップファイル (swap file)とは、使っていないメモリの内容を一時的にしまっておくためのファイルです。(参考3)

### メモリの現状確認
`-m`はメガバイト単位で出力します。以下では、メモリは1G弱で、Swap領域は0であることがわかります。

```
$ free -m

              total        used        free      shared  buff/cache   available
Mem:            985         233          70           0         682         593
Swap:             0           0           0
```

### ddコマンドとは
ddコマンドは、Unix系OSで使える。主な目的はファイルをコピーしたり変換したりすること。例えば、「インストールメディア(CD-ROMなど)を、ISOイメージファイルとして保存する」ために使ったりするらしい（昔の情報）。


例えば以下であれば、全てNULL文字で埋まった100バイトの「file1」というファイルを作成する。

```terminal:例
$ dd bs=100 count=1 if=/dev/zero of=file1
```


**オプション**

`bs`=BYTES: ブロックサイズ。ファイル内において、一度に読み書きできるバイト数
`count`=N: コピーする入力ブロックの数
`if`=FILE: 入力ファイル、/dev/zeroはNULL文字が入っている
`of`=FILE: 出力ファイル

詳細は, [manページ](http://man7.org/linux/man-pages/man1/dd.1.html)を確認ください。



## 実際に空のSwapファイルを作ってみる
### 1M x 1024 = 1024MiB のファイルを作る

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

1024+0 レコード入力
1024+0 レコード出力
1073741824 バイト (1.1 GB) コピーされました、 14.2801 秒、 75.2 MB/秒
```

### Swapファイルとして初期化する

```
$ sudo /sbin/mkswap /var/swap.1

mkswap: /var/swap.1: パーミッション 0644 は安全な値ではありません。 0600 をお勧めします。
スワップ空間バージョン 1 を設定します。サイズ = 1024 MiB (1073737728 バイト)
ラベルはありません, UUID=6b6561f4-6a4d-4384-900c-8d5747ca144a
```
ひとまず警告は無視。

### Swapファイルを有効化する

```
$ sudo /sbin/swapon /var/swap.1

swapon: /var/swap.1: パーミッション 0644 は安全な値ではありません。 0600 をお勧めします。
```

### メモリの確認

```
$ free -m
               total        used        free      shared  buff/cache   available
 Mem:            985         192         700           0          92         667
 Swap:          1023          43         980
```

おっ、Swap領域が増えてる。この後、`composer require` が成功して無事にライブラリをインストールでき、少し感動しました。

翌日、再度メモリを確認してみるとSwapの部分は0バイトになっていたので、これは一時的なSwap領域だと思います。永続的にSwapファイルを作成する方法もあるかと思うので、気になる方は調べてみてください。

## 参考
- [1. composer trouble shooting] (https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors)
- [2. stack overflow: PHP Composer update “cannot allocate memory” error](https://stackoverflow.com/questions/18116261/php-composer-update-cannot-allocate-memory-error-using-laravel-4)
- [3. swapファイルとは](https://wa3.i-3-i.info/word1722.html)
- [4. ddコマンド](https://www.atmarkit.co.jp/ait/articles/1711/30/news027.html)
- [5. スワップ領域を既存パーティション上に確保するには](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/389swapfile.html)