2

私は、c で書かれたカスタム プログラミング言語のいくつかの機能に取り組んできました。現在、言語のオブジェクトの参照カウントを行うシステムに取り組んでいます。これは、c では、とりわけ参照カウントを持つ構造体として表されます。
現在割り当てられているすべてのオブジェクトを解放できる機能もあります (すべてのメモリをクリーンアップするためにプログラムを終了する前など)。ここに問題があります。

どうすればうまくいくかを考えていたのですが、いくつか問題がありました。状況を少しスケッチしましょう。

2 つの新しい整数が割り当てられます。どちらも参照カウントが 1 である 1つの
新しいリストが割り当てられ、参照カウントも 1 である

両方の整数がリストに含まれるようになり、
これらのアクションの後に参照カウントが 2 になります。両方の整数が何らかの理由で範囲外になるため、それらの参照カウントはまだリストにあるため 1 に減少します。

これらのオブジェクトの処理が完了したので、関数を実行して追跡対象のすべてのオブジェクトを削除します。ただし、お気づきかもしれませんが、リストとリスト内のオブジェクトの参照カウントは同じ (1) です。これは、どのオブジェクトを最初に解放するかを決定する方法がないことを意味します。

リストの前に整数を解放すると、リストは以前に解放された整数の参照カウントを減らそうとしますが、これは segfault になります。

整数の前にリストが解放されると、整数の参照カウントが 0 にデクリメントされ、整数も自動的に解放されるため、整数を解放するためにそれ以上の手順を実行する必要はありません。それらはもう追跡されていません。

現在、ほとんどの場合は機能するシステムがありますが、上記の例では参照カウントに基づいてオブジェクトを解放しています。最新の最高カウント。これは明らかに、整数の参照カウントが上記の例で表示されているリストよりも多い場合にのみ機能しますが、常にそうであるとは限りません。(整数が範囲外にドロップされていないため、リストよりも参照カウントが多い場合にのみ機能します)

注:私は本当に好きではない方法をすでに1つ見つけました。すべてのオブジェクトにフラグを追加して、コンテナ内にあるため解放できないことを示します。割り当てられたすべてのオブジェクトにメモリのオーバーヘッドが追加され、循環依存があるとオブジェクトが解放されないため、これは好きではありません。もちろん、サイクル検出器でこれを修正できますが、できれば参照カウントのみでこれを行いたいと思います。

上記の手順の具体例を挙げましょう。


//this initializes and sets a garbage collector object. 
//Basically it's a datastructure which records every allocated object,
//and is able to free them all or in the future 
//run some cycle detection on all objects. 
//It has to be set before allocating objects 

garbagecollector *gc = init_garbagecollector();
set_garbagecollector(gc);

//initialize a tracked object fromthe c integer value 10
myobject * a = myinteger_from_cint(10); 
myobject * b = myinteger_from_cint(10);

myobject * somelist = mylist_init();
mylist_append(somelist,a);
mylist_append(somelist,b);

// Simulate the going out of scope of the integers.
// There are no functions yet so i can't actually do it but this
// is a situation which can happen and has happened a couple of times
DECREF(a);
DECREF(b);

//now the program is done. all objects have a refcount of 1

//delete the garbagecollector and with that all tracked objects
//there is no way to prevent the integers being freed before the list
delete_garbagecollector(gc);

もちろん起こるべきことは、100% の確率で、整数が解放される前にリストが解放されるということです。

コンテナーに格納されているオブジェクトがコンテナーの前に解放されないように、既存のすべてのオブジェクトを解放するよりスマートな方法は何でしょうか?

4

2 に答える 2

1

それはあなたの意図に依存します:

現在割り当てられているすべてのオブジェクトを解放できる機能もあります (すべてのメモリをクリーンアップするためにプログラムを終了する前など)。

参照カウントに関係なく、すべてのオブジェクトを強制的に解放することが目標である場合、オブジェクト グラフをたどり、参照カウントに触れることなく各オブジェクトを解放する個別のコード チャンクが必要になります。ref カウント自体も最終的に解放されるので、更新する意味はほとんどありません。

目標がシステムに「オブジェクトはもう必要ありません」と伝えることだけである場合、別のオプションは単にルートをたどってその参照カウントを減らすことです。それらへの他の参照がない場合、それらはゼロになります。次に、割り当てが解除される前に、参照するすべての参照カウントを減らします。これは、オブジェクト グラフ全体に浸透します。これを呼び出した時点でルートが参照を保持している唯一のものである場合、事実上すべてが解放されます。

于 2019-04-05T20:33:53.207 に答える