dポイントプレゼントキャンペーン実施中!

メモリ解放について、ご教授ください。
C#にて、クラスライブラリ(DLL)を作るのですが、以下のようなクラスの使い方でのメモリ解放をどうにかして実施できないかと思っています。
例)
※全て同プロジェクト内です。
※名前空間は省きます。
※本来はデータ取得用のGETメソッドなどもあるのですが省きます。

class A{
B b;
A(){ b = new B(); }
public void add(string s){ b.add(s); }
public del(){ }
↑ここでBのcやCのsDataを処分してメモリを解放したいです。b=nullとか?
}

class B{
C c;
public B(){ c = new C(); }
public void add(string s){ c.add(s); }
}

class C{
List<string> sData;
public C(){ sData = new List<string>(); }
public void add(string s){ sData.add(s); }
}

最初からList<string>をAで持てば、という点については、無しにして頂ければと思っています。
また、DLLの呼び出し元にあまり手の込ませた手順を入れなくて済むようにしたいため、ドメインのアンロードで解消は除外でお願いします。(アンロードでは解消しない、的外れな意見でしたらすみません)

そもそも、インスタンスクリア後に呼び出し元に戻った時点で、GCの自動稼働で解決するよ、などありましたらそれもお教え下さい。
Aクラス内で、C c = b.c; c.sDataに何かしたら良い?などがあるのかもしれません。そこも私の方でよく分かっていません。

お手数ですが、ご教授頂ければと思います。

A 回答 (2件)

任意削除なら


A(){ b = new B(); }
public del(){ b = new B(); }
でも良いですよ。というか使うたびに if(b==null) とか無駄なので上記が推奨です。

要点は new B(); ではなく b= の部分です。
b=nullに限らず、変数bに何か新しく代入すれば、bがそれまで参照していたオブジェクトは参照を失うためアクセス不能になりガーベージコレクションの対象となります。
# 繰り返しますが、他に生きた参照がある場合は別です
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
newでも解放に至ってくれるのですね。
newは空ではなくて、改めて作る、の印象で、メモリは残ってしまうものと思っていました。
確かにこれならdel後に呼び出し元から再度addをやってもbが空で呼べないは無いですね。
助かりました。感謝です。

お礼日時:2018/07/17 14:51

del()って普通のメンバ関数ですよね。

間違って呼び出してバグになるだけなので止めた方が良いでしょう。
解放処理を書くならデストラクタ~A()を定義してその中でしょうけど、単なるメモリ解放ならガーベージコレクタの領分なのでやる必要ないです。オブジェクトが開いていたファイルを閉じるとか、そういった処理を行ないます。あと他のオブジェクトの中まで触るような書き方をすると呼び出されるタイミングとか順序の問題でバグの原因となりかねないので余計な処理は書かない方が良いです。
ガーベージコレクタがある言語においてオブジェクトはプログラムからアクセスする手段がなくなるとガーベージコレクションの対象となります。質問の例だとクラスAのオブジェクトへのリンクをクリアした時点でその配下にあるb,c,sDataの全オブジェクトが回収対象になりそのうち回収されるでしょう。
# 他に生きた参照がある場合は別です
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
GCでどうにかなるものなのですね。
del()については、呼び出し元任意でデータ削除を行いたいのです。
また、呼び出し元はクラスAのインスタンス破棄をしないため、デストラクタでは難しいのです。
ですので、例のコードが甘かったのですが、クラスAではコンストラクタを辞め、b.add前に「if(b == null) b = new B();」を追加のイメージになります。
ちなみに、del側はb=nullでGCによるメモリ解放はされますか?newをするのはメモリ解放に繋がらない考えでいます。認識違いでしたらすみません。

お礼日時:2018/07/17 11:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!