aws SDK for phpがメモリ漏れてる〜〜〜〜
いや、マジで泣くかと思ったわ
valgrindはメモリのリーク状態を確認出来る便利なツールね
結果が下の表のように返ります
項目 | 概要 |
---|---|
definitely lost | 間違いなくmemory leakを起こしているmemoryの値をbyte単位で出力する |
indirectly lost | pointer base構造上の主構造が消滅し取り残されたmemory leak 値をbyte単位で出力する |
possibly lost | Pointerにて上手く回避されて無いのであればmemory leakする可能性があるmemory leak値をbyte単位で出力する |
still reachable | 開放しなければmemory leakする可能性があるmemory。一般的には問題ない処理である。 |
要するにPHPのヘッダーだけのコード
本当に何もしてない
<?PHP
こいつをまずはvalgrindでチェックしてみる
==2783== LEAK SUMMARY: ==2783== definitely lost: 15,176 bytes in 1,067 blocks ==2783== indirectly lost: 2,662 bytes in 44 blocks ==2783== possibly lost: 0 bytes in 0 blocks ==2783== still reachable: 81,456 bytes in 2,693 blocks ==2783== suppressed: 0 bytes in 0 blocks
こんなん返ってきた
phpのbinaryだけでDefinnnitely lostが15,176 bytes、indirectory lostが2,662 bytes、合計で17,838 bytesのleak memoryが存在しているのが分かる。
このleak自体は実は問題が無い
こいつのleakは子Proccessでも何でも無いのでOS側のmemory managerがよしなに開放してくれちゃうからだ
別に難しいことはしないで
SDKでdescribeInstancesを実行してEC2の情報と取りに行くだけのコードを実行してみる
<?php require 'aws/aws-autoloader.php'; use Aws\Ec2\Ec2Client; use Aws\Common\Enum\Region; $objEc2Client = Ec2Client::factory(array('region' => Region::TOKYO)); $result = $objEc2Client->describeInstances();
phpのコード中にleak memoryが存在していないと何も実行していないphpと同じ内容になるはず!
でもね。これが結果なのよ
==2723== LEAK SUMMARY: ==2723== definitely lost: 16,256 bytes in 1,071 blocks ==2723== indirectly lost: 28,107 bytes in 83 blocks ==2723== possibly lost: 0 bytes in 0 blocks ==2723== still reachable: 165,793 bytes in 4,108 blocks ==2723== suppressed: 0 bytes in 0 blocks
definnnitely lostが16,256 bytes、indirectory lostが28,107 bytes、44,363 bytes合計で存在している。
何も実行していないphpのmemory leak合計値が17,838 bytesなので差分値26,525 bytesがSDKの実行によって生じたmemory leakであると確認出来る訳ね
ほ〜〜ら、usedがガンガン増えてfreeがめちゃくちゃ減ってる
これ、10秒に1回呼び出した結果ね
1時間で3600秒だから1時間で360回呼ばれてるわけだ
つまり、1年間稼働して1日1回SDK for phpの呼出が在るとして
365日×26,525byte=9,681,625 byte
1回のsdkの命令の呼出を毎日やるとして年間で10Mbyteほどのメモリがleakします。
実際は1回の呼出ではなく、各sdk内でhttps通信が発生する度に起きているので×n回分な訳だ
はい、ぶっちゃけると
aws sdk for php内でhttps通信に使われているGuzzleライブラリの中で呼び出しているlibCurlのphp extensionが使用しているlibnssライブラリの中です。
Guzzleライブラリはこの辺りは結構カバーしてて対策をとっているのだけど
対策が取られてるのってGuzzleの4系列でaws sdk for phpで使われているのは対策が取られていない3系列
で、この手のbugって結構、対策しても改修の度にまた再発って多いのでcurlやnssの動向は追っておこうね
そういう訳で定期的に呼び出す類のscriptはaws SDK for phpは避けた方が良いよん
元記事はこちらです。
「”memory leak”が止まらない | 雲間を泳ぐ」