2

簡単なプログラミング言語を実装しようとしています。ユーザーがメモリを管理する必要がないようにしたいので、ガベージコレクターを実装することにしました。いくつかの資料をチェックした後に考えることができる最も簡単な方法は次のとおりです。

2 種類のヒープ ゾーンがあります。1 つ目は大きなオブジェクト (85,000 バイト以上) を格納するためのもので、もう 1 つは小さなオブジェクトのためのものです。以下では、最初に BZ を使用し、2 番目に SZ を使用します。

大きなオブジェクトの移動にはコストがかかるため、BZ はマーク アンド スイープ アルゴリズムを使用します。圧縮しないので、断片化があります。

SZ は、mark-compact の世代を使用します。ジェネレーションは 0、1、2 の 3 つです。割り当て要求は直接ジェネレーション 0 に送られ、ジェネレーション 0 がいっぱいになるとガベージ コレクションが実行され、サバイバーはジェネレーション 1 に昇格されます。ジェネレーション 1 とジェネレーション 2 はいっぱいになったらガベージコレクションも行います。

仮想マシンが起動すると、OS から大きなメモリが割り当てられ、仮想マシンのヒープ ゾーンとして使用されます。BZ と SZ のすべての世代がメモリの固定部分を占有し、割り当て要求ができない場合満たされると、仮想マシンはエラー OTM (メモリ不足) を返します。これには問題があります。仮想マシンが起動すると、プログラムを実行するのに必要なメモリはわずかですが、それでも大量に使用されます。より良い方法は、仮想マシンが OS から少量のメモリを取得し、プログラムがより多くのメモリを必要とするときに、仮想マシンが OS からより多くのメモリを取得することです。SZ でジェネレーション 2 に大きなメモリを割り当て、ジェネレーション 2 のすべてのものを新しいメモリ ゾーンにコピーします。BZ についても同じことを行います。

もう 1 つの問題は、BZ がいっぱいで SZ が空の場合に発生します。実際には SZ にビッグ オブジェクト用の十分な空きヒープ サイズがあるにもかかわらず、ビッグ オブジェクトの割り当て要求を満たすことができないというのはばかげています。この問題に対処するには?

4

1 に答える 1

4

私はあなたの方法論を理解しようとしています。あなたはあなたの戦略を完全に言及していないので、私はいくつかの仮定を持っています.

: 以下は私の仮説的な分析であり、実際には不可能な場合があります。時間がない場合は回答を飛ばしてください。

Generational GC を変更して使用しようとしています。2種類の分類があります

(1) 大きなサイズのオブジェクトBZおよび

(2)小さいサイズのオブジェクトSZ .

SZは、コンパクションを使用して世代別 GC を実行します ( CMS )

上記の理解から、SZG2には長寿命のオブジェクトがあることがわかります。長寿命のオブジェクトは一般に長生きする傾向があるため、szG2 の GC はSZG1や SZG0ほど頻繁ではないと予想しています。 SZG2 で頻繁に GC を実行すると、 SZG1 または SZG0比べて生産性が低下します (長い GC スパイク、ユーザーにとって顕著な遅延) 。

同様に、BZの場合、大きなメモリが必要になる場合があります (大きなオブジェクトがより多くのスペースを占有するため)。ですから、あなたの質問に答えるために

"The other problem occurs when the BZ is full and SZ is empty, I would be silly not be able to satisfy a big object allocation request even though we in fact have enough free heap size for the big object in SZ. How to deal with this problem?"

「プログラムがより多くのメモリを必要とするとき、仮想マシンは OS からより多くのメモリを取得する」と言ったので、

私には小さな考えがあります。生産的でないか、実装できない可能性があり、GCHeap構造の実装に完全に依存している可能性があります。仮想マシンに次のようにメモリを割り当てさせます

ここに画像の説明を入力

以下の可能性(以下に示す「プログラムのメモリセグメント」からアイデアを借りました)は、低レベルで可能です。

ここに画像の説明を入力

上の図に示すように、 GCHeap 構造は、 SZG0BZが互いに拡張するように定義する必要があります。図a図 bで説明したGCHeap 構造を実装するには、ゾーンSZG[0 -2]サイズとBZ

したがって、アプリケーションのヒープを複数のヒープに分割する場合は、図 A図 Bの上に重ねて、断片化を減らすことができます (断片化と言うときit means "when the BZ is full and SZ is empty, I would be silly not be able to satisfy a big object allocation request even though we in fact have enough free heap size for the big object in SZ.")。

したがって、効果的な構造は

            B
            |
            B
            |
            B
            |
            B
            |
            A

GCHeapA 、 GCHeapB などの複数の GCHeap 構造で GCHeap データ構造を考慮するか、要件に基づいて単一のヒープとして使用するかを決定するヒューリスティックに完全に依存します。

複数のヒープを持ちたくない場合は、次のように小さな修正を加えて図 A を使用できます。Setting base address of **SZG2** to top of heap

図 a の背後にある主な理由は次のとおりです。SZG0 が頻繁に GC されることがわかっているため、 SZG1およびSZG2 と比較してより多くの空き領域を確保できます。これは、死んだオブジェクトが削除され、生き残ったオブジェクトがSZG1およびSZG2に移動されるためです。 BZSZG0に向かって成長することができます。

図では、 SZG1SZG2のベース アドレスが 連続しています。これは、 SZG2がメモリ不足エラーを起こしやすいためです。これは、古い世代のオブジェクトがより長く存続する傾向があり、GC があまりスイープしないためです (注:これは単なる私の仮定と意見です)。したがって、SZG2外側にバインドされたままです。

于 2013-02-27T17:46:07.063 に答える