ログイン



メモリ管理

※この内容はPHP6に特化した内容ではありません。

PHPなどのスクリプト言語は、基本的には、メモリ管理を意識せずに利用できます。とはいうものの、大容量のCSVを生成するなど、大量にメモリを消費するプログラムを作成するのであればメモリ管理について知っておくべきです。

1.メモリ解放は参照が消失時

以下のプログラムを実行すると、まず、文字列”Hello Memory Management”が生成され、その参照が$hogeに格納される。2行目で$hogeをunsetすることで、文字列”Hello Memory Management”への参照がなくなり、メモリが解放される。

1
2
$hoge = "Hello Memory Management";
unset($hoge);

unsetが特別な意味を持っているのではなく、文字列への参照が無くなればメモリは解放される。true代入すると、元の文字列への参照は無くなるので、メモリは解放される。

1
2
$hoge = "Hello Memory Management";
$hoge = true;

参照が失われた時点でメモリが解放されていることの確認

長さ50の文字列を120万個生成し、配列に代入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for($i=0;$i<1200000;$i++){
    if($i % 100000 == 0)echo $i."<br>";
    $cash[$i] = '12345678901234567890123456789012345678901234567890';
}
実行結果
0
100000
200000
300000
400000
500000
600000
700000
800000
900000

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 51 bytes) in C:\xampp\htdocs\mem.php on line 4
#メモリ不足でエラー発生

長さ50の文字列を代入後、長さ0の文字列で上書きを120万回繰り返す。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for($i=0;$i<1200000;$i++){
    if($i % 100000 == 0)echo $i."<br>";
    $cash[$i] = '12345678901234567890123456789012345678901234567890';
    $cash[$i] = '';
}

実行結果
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
1100000
#最後まで実行できた。

長さ50の文字列は破棄され、長さ0の文字列120万個がメモリ内に残るだけなので、最後まで実行できる。

2.代入した値が複製されるのは、代入された値が変更された時点

先程とよく似ていますが、最後まで実行できる。$cash[0……1199999]には、同じ文字列への参照が入っているだけなので、メモリの消費量は少ない。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$str = '12345678901234567890123456789012345678901234567890';
for($i=0;$i<1200000;$i++){
    if($i % 100000 == 0)echo $i."<br>";
    $cash[$i] = $str;
}
実行結果
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
1100000

4行目で代入した時点では、オブジェクトは複製されない。しかし、5行目で文字列結合で、新しいオブジェクトが生成されるため、メモリ不足が発生し、プログラムは途中で止まってしまう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$str = '12345678901234567890123456789012345678901234567890';
for($i=0;$i<1200000;$i++){
    if($i % 100000 == 0)echo $i."<br>";
    $cash[$i] = $str;
    $cash[$i] .=''';
}

実行結果
0
100000
200000
300000
400000
500000
600000
700000
800000
900000

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes) in C:\xampp\htdocs\mem.php on line 5

まとめ

  • unsetを実行しなくても、参照がなくなった時点でメモリは解放される。

4 Responses to “メモリ管理”

  1. […] Togetter – まとめ「宇野さんと豊崎さん」fc2:1 メモリ管理fc2:1 […]

  2. […] This post was mentioned on Twitter by My Rss Feed, Takayuki Fuwa. Takayuki Fuwa said: [B!] メモリ管理 http://php6.jp/tips/%E3%83%A1%E3%83%A2%E3%83%AA%E7%AE%A1%E7%90%86/ […]

  3. […] 一週間ほど前に公開した、Tips/メモリ管理ですが、説明文に読みにくい箇所、説明不足の箇所があったので加筆修正しました。今週末中に、名前空間を完成させようと思っています。 […]

Leave a Reply