HaskellやIdrisのような、ガベージコレクションのないシステムプログラミングを目的とし、ランタイムがない(または少なくともCおよびRust 「ランタイム」)ベアメタルで実行できるもの。
手動のメモリ管理やランタイムガベージコレクションを必要としない静的メモリの安全性のオプションにはどのようなものがありますか。また、HaskellまたはIdrisに類似した純粋な関数の型システムを使用して問題を解決するにはどうすればよいですか。
通知 のメモリ管理 は、明示的かつ手動(手書きのCコードなど)、ガベージコレクション、または所有権ベースのいずれかです。 GCハンドブック (または少なくとも に関するPaul Wilsonの調査)niprocessor Garbage Collection Techniques )。 GCは非常に効率的であることに注意してください(問題があるが興味深い古いAppelの論文を読んでください: ガベージコレクションはスタック割り当てよりも高速である可能性があります )
(ガベージコレクションはあいまいな概念です。自動参照カウント、トレース、またはGCの移動などを含む、あらゆる種類のautomaticメモリ管理手法として定義されることが多いことに注意してください。)
Cにコンパイルされたexisting関数型プログラミング言語の多くの実装を調べましたか?それらのいくつかは、巧妙な技術を使用しています。 チキンスキーム ( MTAのチェニーについて読む )
私の考えでは、高次関数型プログラミングにはガベージコレクションに近いものが必要です(クロージャーはレキシカルスコープよりも長く存続できるため)。
おそらく、コンパイル時のガベージコレクション(および領域ベースのガベージコレクション)についてグーグルするかもしれません。
多分あなたはGCが書かれている関数型プログラミング言語が欲しい-実際にはGCはあまり割り当てを行わないその言語のサブセットで書かれているであろう-だがそれは別の問題である(例えば内部のPreScheme方言を見て Scheme48 )。
実際には、C標準のmalloc
はnotをベアメタルで実行します(ただし、一部の オペレーティングシステム より上)。通常、 システムコール の上に構築され、 仮想アドレス空間 を処理して拡張します(例 mmap(2 ) etc ... on Linux)。 OSの概念に慣れていない場合は、 オペレーティングシステム:3つの簡単な部分 をお読みください。
ところで、あなたの言語 をC にコンパイルし、existingガベージコレクター(例 [〜#〜] mps [〜#〜] 、 Boehm 、....);または、言語をマシンコードにコンパイルすることを検討できます。ただし、既存のシステムコールを使用します(C標準ライブラリにさえ依存しない、Cに依存しないScheme実装の興味深い例として Bones を調べてください)。
Jeremie SalvucciとE.Chaillouxの論文も参照 関数型言語と命令型言語のメモリ消費分析
この側面で非常に興味深い、私が使用した他の1つのスキームは SwiftおよびObjective-Cの自動参照カウント です。
慣れていない場合、参照カウントは、各オブジェクトがいくつかの状態を持っている(したがって、関数型プログラミングには適していない可能性があります。私はよくわかりません)、他のオブジェクトが使用している数を追跡します。手動参照カウントでは、新しいオブジェクトを割り当てると、オブジェクトの参照カウントは1になります。別のオブジェクトがそのオブジェクトを使用したい場合、オブジェクトで「保持」メソッドが呼び出され、参照カウントがインクリメントされます。完了すると、「解放」が呼び出され、参照カウントが減少します。参照カウントが0に達すると、オブジェクトは自身を削除します。
これは手動の参照カウントです。自動参照カウントでは、開発者が明示的に何かを保持したり解放したりすることはありません。コンパイラーがそのすべての詳細を処理します。オブジェクトを割り当てるだけで、まるで魔法のように、使用を終えると解放されます。魔法は、割り当てや呼び出しなどのことを行うと、コンパイラーがそれに気づき、保持および解放することです。これには、コードにいくつかの追加の注釈が含まれるため、コンパイラーはオブジェクトの使用方法を理解できます。たとえば、保持する値を「強い」としてマークし、使用していても所有していない値を「弱い」としてマークすることができます。ほとんどの場合は適切なデフォルトであるため、デフォルトで十分なので、ほとんどの値に注釈を付ける必要はありません。
これはガベージコレクションに類似していることが示唆されています。同意しません。たとえば、 ARCに関するWikipediaの記事 は次のように述べています。
ARCは、実行時にオブジェクトを非同期的に割り当て解除するバックグラウンドプロセスがないという点で、ガベージコレクションのトレースとは異なります。
手動の参照カウントを行う場合、多くの場合、自動解放プールがあるため、クリーンアップせずに複数のイベントループに行くことはありません。実際、希望する任意のスコープでいつでも自動解放プールを作成できるため、開発者が制御します。 。他の作業を中断する可能性がある未知の将来の時間には起こりません。また、自動的に行われる場合、ガベージコレクションとはまったく異なります。私が理解しているように、たとえば、古いオブジェクトから新しいオブジェクトにポインタを割り当てると、メモリの解放がすぐに行われます。これは、定期的にクリーンアップを実行するガベージコレクターとは大きく異なり、malloc
やfree
などを使用してリソースを手動で処理する方法に非常に近くなります。私の経験では、参照カウント、特に自動参照カウントのパフォーマンスへの影響は、ガベージコレクションよりも優れ、予測可能です。しかし、私はガベージコレクションをあまり行っていないことを認めます。