多数の大きなオブジェクトを使用します。理想的には、それらすべてをクライアント コードで永続的に利用できるようにしたいと考えていますが、一度にすべてを物理メモリに収めることはできません。そのため、メモリの制限に近づくと、プール内のオブジェクトの一部を破棄する必要があります (おそらく、使用頻度の最も低いオブジェクトを破棄します)。(ディスク上の仮想メモリを使用することは、システムが完全にフリーズすることと同じです。)
具体的には、オブジェクトあたりのメモリは ~100MB から ~10GB の間で変化します。私たちが持っている RAM の総量は 32GB です。
残念ながら、各オブジェクトが使用するメモリは、作成されるまでわかりません。したがって、特定のオブジェクトが利用可能な物理メモリに収まるかどうかを予測することはできません。
適切な解決策は、Python メモリ アロケータにコールバック関数を提供し、空き物理メモリの量が特定のしきい値を下回ったことを確認したときにメモリ アロケータがそれを呼び出すようにすることです。そのコールバック関数は、単にプールからオブジェクトを破棄して戻ります。一般に、メモリがすぐに利用可能になるという保証はありませんが、CPython (参照カウンターがゼロになった瞬間にメモリを解放する) では確実に利用可能になります。
残念ながら、メモリが少なくなったときに Python メモリ アロケータに提供された関数を呼び出させる方法を私は知りません。他にできることはありますか?
バックグラウンドで別のスレッドを実行し、使用可能なメモリを毎秒程度チェックすることができると思います。使用可能な物理メモリが 5GB 未満であると判断した場合、プールからオブジェクトを破棄し始めます。オブジェクトの破棄が平均して少なくともオブジェクトの作成と同じ速さで進行すると仮定すると、5GB のクッションはあまり使い果たされず、問題ありません。これはかなり壊れやすいようです。しかし、このアプローチの実装のアイデアはまだ素晴らしいでしょう。
これは Python 3.2 の下の Linux で動作する必要がありますが、Windows 用の (おそらく異なる) ソリューションがあればいいでしょう。
注:メモリ割り当ての 3 つの層が機能しています: OS、malloc
(C ランタイム)、および Python オブジェクト アロケータ。