AWS SDK for PHP がメモリ漏れてる〜〜〜〜
いや、マジで泣くかと思ったわ
Valgrindで確認してみた
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がよしなに開放してくれちゃうからだAWS SDK for PHP を実行してみる
別に難しいことはしないで
SDKでdescribeInstancesを実行してEC2の情報と取りに行くだけのコードを実行してみる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 blocksdefinnnitely lostが16,256 bytes、indirectory lostが28,107 bytes、44,363 bytes合計で存在している。
何も実行していないphpのmemory leak合計値が17,838 bytesなので差分値26,525 bytesがSDKの実行によって生じたmemory leakであると確認出来る訳ね実際に組み込んで1時間動かした結果
ほ〜〜ら、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”が止まらない | 雲間を泳ぐ」