2017/02/07

[c/c++]メモリのフラグメンテーションを減らしたい

久々に、Cで実装している。

今回、アプリから受け取ったデータをプロトコルに変換するようなライブラリを作っている。
アプリのデータサイズは想定できないし、プロトコル長の最大も決めづらい。
また、いくつプロトコルデータをアプリが持ちたいかも決められない。

となると、ヒープを使うしか無かろう。
malloc/freeだ。
あー、苦手なのよねぇ。。。

C++だとデストラクタでメモリ解放する、ということもできそうだが、Cだと思いつかない。
メモリの管理だけのためにまたメモリの使用量を増やすというのは、やりたくない。


まあ、そういうのは私が解決せんといかんことだろうが、別の点で気になることがある。
メモリのフラグメンテーションだ。

10年前、いや、もう少し前になるだろうか。
今よりも多少冴えていて、体力もあった私は、C++で組み込みアプリを実装していた。
画像データを扱ったり、画像をファイルに変換したりしていたので、new/deleteしていた。
デストラクタでメモリ解放漏れのチェックなんかもして、そういう方面は問題なかろうと思っていた。

が、だ。
テストのため、帰る前に自動で処理するようにしておき、翌日見に行くと、どうも処理が遅いような気がする。
気のせいかと思って、土日に連続運転させて月曜日出社すると、1秒もかからずに終わっていた処理が、分単位でスローモーションのように動いていたのだった。。。

メモリの解放漏れなどないのに!?と思ってあちこちの人に聞いたところ、メモリのフラグメンテーションではないか、という意見があった。
試しに、画像処理のメモリを毎回new/deleteしていたところを、最初にnewしたまま使い回すように変更したら、発生しなくなった。

いやぁ、そこそこ組み込みの世界を理解してきたと思い込んでいただけに、衝撃でしたわ。
Linuxだと、メモリが分断されても、うまいことOSがつながった大きい領域に見せかけて使うことはできるのだけど、あくまでソフトウェアとしてつながって見えるだけで、分断された部分を使う処理の負荷が大きくなったとか、そんなことだったと思う。
Linux 2.18とか、そのくらいだったと思うので、今はまた事情が違うかも。

 

それ以来、ヒープメモリの確保と解放に怯えるようになりましたとさ。
めでたしめでたし。


Boostには、メモリプールというやつがあって、そういうフラグメンテーションが置きにくいようにできる、というのを読んだ気がする。
やったことないので、リンクだけ載せておこう。

Chapter 4. Boost.Pool

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。