いくつかのLisp実装は、優れたガベージコレクタを備えています。特別な問題は、Lispアプリケーションがしばしば小さなオブジェクト(conses、...)の高い割り当て率を持つことです。
考慮すべき点がいくつかあります。
Precise vs. Conservative GC。私はLispの保守的なGC(Boehmなど)の巨大なファンではありません。保守的なGCの問題は、すべてのゴミが見つからないということです。これは、長時間実行されているプログラムでは問題になる可能性があり、フラグメンテーションにつながり、未使用のメモリを再利用することはありません。正確なGCはLispデータのタグ情報を使用しており、すべてのオブジェクトのすべてのデータ型を識別できます。保守的なGCは、タグ付きデータを使用しないプログラミング言語の実装(C++、...)のために考案されました。
コピーGC、圧縮GC。長時間実行するLispsでメモリの断片化を防ぐために、オブジェクトを圧縮してローカライズするGCが便利です。ハッシュテーブルを再ハッシュしなければならない場合(場所が変更されるため)、時には問題が発生します。コピーGCはより多くのメモリを必要とする可能性があります(メモリのfromとaのスペースがあるため)。しかし、GCがオブジェクトをあるメモリ空間から別のメモリ空間にコピーすると、自動的にコンパクトになります。より高度なGC(Lispマシンのような)は、オブジェクトをソートし、同じタイプのオブジェクトを互いに近くに割り当てることができます - これがオブジェクトへのアクセスを高速化すると仮定します。
一時的GC。これは、主メモリ内で排他的に実行される第1のGCステージが存在し、メモリ管理ユニットから何らかのサポートを得て、変更されたメモリ領域を特定することを意味する。メインメモリのスキャンは仮想メモリのスキャンより高速であり、変更されたメモリ領域のスキャンだけで作業量がさらに減少します。たくさんのオブジェクトが割り当てられ、すばやくガベージに変わると、GCの一時停止が非常に短くなります。
世代GC。通常、今日のGCは世代的なものです。複数の世代が存在し、いくつかのGCで生存するオブジェクトは古い世代に昇格されます。通常、第1世代のみがGCedされます。
チューニング。 LispWorksとAllegro CLのGCには、多くのチューニングノブがあります。特に長時間実行されるアプリケーションの場合は、マニュアルを読んで、世代数やサイズなどを調整するのが理にかなっています。
仮想メモリ。仮想メモリ上のGCは通常非常に遅いです。可能であれば、マシンにRAMを追加しないでください。
手動メモリ管理。たとえば、CL-HTTP Webサーバーは、リソースを使用して手動でメモリ管理を行います。これらは、事前に割り当てられたオブジェクトのプールであり、非常に迅速に再初期化できます。 Lispマシンはこれをたくさん使っていました。それらの典型的な用途は、ストリームのための読み出しバッファにある。すべての読み取り操作で新しい文字列を作成するのではなく、再利用可能なバッファーを使用すると便利です。
スタック割り当て。いくつかのCommon Lispでは、いくつかのデータのスタック割り当てが許可されます。ブロックを残すと自動的にメモリが解放されます。これは、ブロックを離れるときにメモリがもはや参照されないことを前提としています。
同時GC。通常のCommon Lisp実装では、並行GCと同時Lispスレッドのサポートはありません。いくつかの実装では、同時Lispスレッドがありますが、GCは動作中にそれらをすべて停止します。 GCをプロファイリングするステップとを含む。割り当てがどこで行われているかわからない場合は、プロファイリング情報を使用してGCを調べる必要があります。
Lispにメインメモリで実行される正確な世代GCがある場合、長いポーズでは問題が発生しません。例えば、Clozure CL(無料のCommon Lisp実装)は、非常に良いGC実装を持っています。仮想メモリ内のメモリの断片化やガベージコレクションを回避する必要があります。必要であれば、より多くのメインメモリを持つ64ビットLisp実装を使用してください。
ポインタ:あなたはそのLispWorksドキュメントから見ることができます
とAllegro CLにはチューニング用のノブがたくさんありますGC。
Common Lispには実装環境を扱う関数がいくつかあります。 (ROOM)は、メモリ使用量の概要を示す関数です。 (ROOM t)は、より詳細な情報を提供しています(ここLispWorks):
CL-USER 2 > (room t)
Generation 0: Total Size 1823K, Allocated 1090K, Free 725K
Segment 2008AAB8: Total Size 507K, Allocated 361K, Free 142K
minimum free space 64K,
Awaiting promotion = 0K, sweeps before promotion =10
Segment 217E7050: Total Size 1315K, Allocated 729K, Free 582K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =2
Generation 1: Total Size 1397K, Allocated 513K, Free 871K
Segment 20CB9A50: Total Size 68K, Allocated 48K, Free 15K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =4
Segment 216D7050: Total Size 1088K, Allocated 331K, Free 752K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =4
Segment 2004E4F8: Total Size 241K, Allocated 133K, Free 103K
minimum free space 0K, static
Generation 2: Total Size 2884K, Allocated 1290K, Free 1585K
Segment 21417050: Total Size 2816K, Allocated 1227K, Free 1584K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =4
Segment 20DA5DA0: Total Size 68K, Allocated 62K, Free 1K
minimum free space 117K,
Awaiting promotion = 0K, sweeps before promotion =4
Generation 3: Total Size 19373K, Allocated 19232K, Free 128K
Segment 20109A50: Total Size 11968K, Allocated 11963K, Free 0K
minimum free space 3K,
Awaiting promotion = 0K, sweeps before promotion =10
Segment 20DB6E18: Total Size 6528K, Allocated 6396K, Free 128K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =10
Segment 20CCAAC8: Total Size 876K, Allocated 872K, Free 0K
minimum free space 0K,
Awaiting promotion = 0K, sweeps before promotion =10
Total Size 25792K, Allocated 22127K, Free 3310K
どのlisp実装を使用していますか? – Zifre
"私は推測しています"と言えば、プロファイリングをしなくても最適化をしようとしているようです。あなたの環境で修正が必要な特定の問題が発生していますか? – Ken
私はまだ現れていない問題について自分自身に説明するプロセスを開始しています。 Webサービスで使用されているGC言語の量を考えると、これは主に解決された問題であると私は考えています。 –