Valgrindが示すように、エクストラヒーププログラムメモリ消費
-
28-10-2019 - |
質問
私のプログラムは多くのメモリを使用しています。これは、Valgrind Massifツールが私に示しているものです。
--------------------------------------------------------------------------------
n time(i) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
28 38,531,086,036 760,235,208 143,002,822 617,232,386 0
ご覧のとおり、余分な部分は有用なヒープよりも数倍大きくなります。
この余分なメモリを減らすにはどうすればよいですか?割り当てが少なくなりますか?
これはいわゆる記憶の断片化ですか?
OS:Linux 2.6。プログラムはCで記述されています。24 7で動作するはずで、多くのデータを操作します。
解決
非常に小さなオブジェクトをたくさん割り当てていますか?たとえば、たとえば、ほんの数バイトですか?すべての割り当てに関連する一定量のオーバーヘッドがあります(例えば、 free
ブロックの大きさを伝えることができる必要があります)。
これは、「外部断片化」とは対照的に「内部断片化」と呼ばれることもあります。この「外部断片化」では、いくつかの計算されていないメモリがありますが、使用するには小さすぎるブロックに分割されているため、使用できません。 (もう1つの理由 malloc
本当に小さなブロックが戻っていないことは、これが外部の断片化を減らすのに役立つためです。)
もし、あんたが それは 非常に小さなオブジェクトの多くを割り当てるには、ヒープに個別に割り当てるのではなく、個別に管理することを検討する必要があります。これは、他の方法でも適している場合(たとえば、メモリの局所性を改善します)、正しく行う場合にも優れている可能性があります。
他のヒント
による ドキュメンテーション, 、「エクストラヒープ」バイトは次のとおりです。
その時点で割り当てられた追加のヒープバイトの数。これは、プログラムが要求したものを超えて割り当てられたバイト数を反映しています。余分なヒープバイトの2つのソースがあります。
まず、すべてのヒープブロックには、それに関連付けられた管理バイトがあります。管理バイトの正確な数は、アロケーターの詳細によって異なります。デフォルトでは、Massifは例からわかるように、ブロックごとに8バイトを想定していますが、この数値は - Heap-Adminオプションを介して変更できます。
第二に、アロケーターはしばしば、通常は8または16のより大きな数に要求されたバイト数を切り上げます。これは、ブロック内の要素が適切に整列されていることを確認するために必要です。 nバイトが要求された場合、Massifは、-alignmentオプションで指定された値の最も近い倍数にnを丸めます。
これは私にとって記憶の断片化のようには聞こえません。
メモリの断片化は、通常、多くの小さな割り当てによって引き起こされます。割り当てられたメモリの各ユニット間の小さなギャップになり、より大きな割り当てのために隣接するメモリの領域を取得することが困難になります。
メモリの割り当てを防ぐために、基本的に割り当てが少なくなります!可能な限りスタックスペースを使用します(たとえば不必要に新しい使用しないでください)、可能であれば検討してください プーリング 頻繁にオブジェクトを割り当てて、メモリを割り当て続けないようにします。
大きいサイズの割り当てを減らすか、ヒープを微調整することができます。後者は実装固有になります。
これは断片化ではありません。たとえば7バイトを要求するとき、ヒープが割り当てられます 7バイト以上 - それは16バイトと言うことができるので、9バイトは「余分」になり、実際に無駄になります。これは、さまざまな理由で行われます。たとえば、アラインメントを維持するためです。