あなたの教授は重要な点を提起しています。残念ながら、英語の用法は、彼らが何を言っているのか完全にはわかりません。特定のメモリ使用特性を持ち、私が個人的に取り組んだおもちゃ以外のプログラムの観点から質問に答えさせてください。
一部のプログラムは正常に動作します。それらは、メモリをウェーブで割り当てます。繰り返しのサイクルで、多くの小規模または中規模の割り当てと、それに続く多くの解放です。これらのプログラムでは、一般的なメモリアロケータはかなりうまく機能します。それらは解放されたブロックを合体させ、ウェーブの終わりに、解放されたメモリのほとんどは大きな連続したチャンクになります。これらのプログラムは非常にまれです。
ほとんどのプログラムはうまく動作しません。それらは、非常に小さいものから非常に大きいものまでのさまざまなサイズで、多かれ少なかれランダムにメモリを割り当ておよび割り当て解除し、割り当てられたブロックの高い使用率を保持します。これらのプログラムでは、ブロックを合体させる機能は制限されており、時間の経過とともに、メモリは非常に断片化され、比較的連続しなくなります。合計メモリ使用量が32ビットメモリスペースで約1.5GBを超え、(たとえば)10MB以上の割り当てがある場合、最終的に大きな割り当ての1つが失敗します。これらのプログラムは一般的です。
他のプログラムは、停止するまでメモリをほとんどまたはまったく解放しません。実行中にメモリを段階的に割り当て、少量のみを解放してから停止します。停止すると、すべてのメモリが解放されます。コンパイラはこんな感じです。VMもそうです。たとえば、それ自体がC ++で記述された.NETCLRランタイムは、おそらくメモリを解放することはありません。なぜそれが必要ですか?
そしてそれが最終的な答えです。プログラムのメモリ使用量が十分に多い場合、mallocとfreeを使用してメモリを管理するだけでは、問題に対する十分な答えにはなりません。幸運にも正常に動作するプログラムを処理できる場合を除いて、メモリの大きなチャンクを事前に割り当ててから、選択した戦略に従ってサブ割り当てする1つ以上のカスタムメモリアロケータを設計する必要があります。プログラムが停止する場合を除いて、無料で使用することはできません。
あなたの教授が何を言ったかを正確に知らなくても、本当に生産規模のプログラムのために、私はおそらく彼らの側に出てくるでしょう。
編集
私はいくつかの批判に答えるつもりです。明らかに、SOはこの種の投稿には適していません。明確にするために、私はこの種のソフトウェアの作成に約30年の経験があり、いくつかのコンパイラーも含まれています。私には学術的な言及はなく、私自身の打撲傷だけです。経験がはるかに狭く、短い人々からの批判を感じずにはいられません。
重要なメッセージを繰り返します。mallocとfreeのバランスをとることは、実際のプログラムでの大規模なメモリ割り当てに対する十分な解決策ではありません。ブロック合体は正常であり、時間がかかりますが、それだけでは十分ではありません。真面目で賢いメモリアロケータが必要です。メモリアロケータは、メモリをチャンクで取得する傾向があり(mallocなどを使用)、ほとんど解放されません。これはおそらくOPの教授たちが念頭に置いていたメッセージであり、彼はそれを誤解していた。