私は C++ プログラマーで、個人プロジェクトで D の使用を検討しています。ガベージ コレクターを完全に無効にする方法があるかどうか、また、そうした場合のリスクは何か知りたいです。
new と delete をオーバーライドして malloc と free を使用することで独自のメモリを管理できることはわかっていますが、そうする場合はガベージ コレクターをまったく実行しないようにします。
ベストアンサー1
D2 で GC をオフにするには:
import core.memory;
void main(string[] args) {
GC.disable;
// Do stuff.
}
D1/フォボスを使用する場合:
import std.gc;
void main(char[][] args) {
std.gc.disable;
// Do stuff.
}
D1/タンゴの場合:
import tango.core.Memory;
void main(char[][] args) {
GC.disable;
// Do stuff.
}
GC は、GC.enable (D2 または D1/Tango) または std.gc.enable (D1/Phobos) を呼び出すことで同様に再度有効にできます。これらは、プログラムのどの時点でも実行できます。内部的にはカウンターが使用され、実際に GC を再度有効にするには、disable() が呼び出されるたびに enable() を 1 回呼び出す必要があります。
GC が無効になっている場合は、メモリ リークが発生するため、以下の操作は行わないでください。
- 配列追加 ( ~= ) 演算子を使用したり、.length プロパティを使用して、すでに割り当てられている配列を拡大したりしないでください。これらは、プログラムのどこかにエイリアスが存在する可能性があるため、古い配列を再割り当てする必要がある場合に、GC によって古い配列を解放することに依存します。
- 組み込みの連想配列を使用しないでください。これらを解放する唯一の方法は GC を使用することです。
- Phobos と Tango のほとんどは、ガベージ コレクションが存在することを前提として設計されています。これらのライブラリの関数は、GC なしで使用すると、ひどいメモリ リークが発生する可能性があります。
- GC が無効な状態で D2 クロージャを使用しないでください。(ゲームではそうすることはないと思いますが。)
とはいえ、D は、いくつかの重要なコード部分 (リアルタイム制約が存在するような重要な部分で、リアルタイム コンピューティング用に明示的に設計されていない malloc 形式は使用すべきではない) で GC を無効にして使用できるように設計されていますが、大部分は GC が存在することを前提として設計されています。あなたの場合、すべての初期化などに GC を使用し、ゲームで実際にリアルタイムにする必要がある部分に到達したときにのみ GC を無効にすることができます。
補足として、D では GC と手動のメモリ管理が共存できます。実際、コードを最適化するときに、ライフタイムが短い大きなオブジェクトを手動で削除すると、大幅なスピードアップが実現できます。これは、C++ と同様に delete ステートメントを使用して実行でき、GC が有効になっている場合でも安全に実行できます。リアルタイムの制約がない場合は、手動のメモリ管理のパフォーマンスのほとんどを維持しながら、GC の利点のほとんどを得ることができます。