
メモリ解放について、ご教授ください。
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に何かしたら良い?などがあるのかもしれません。そこも私の方でよく分かっていません。
お手数ですが、ご教授頂ければと思います。
No.2ベストアンサー
- 回答日時:
任意削除なら
A(){ b = new B(); }
public del(){ b = new B(); }
でも良いですよ。というか使うたびに if(b==null) とか無駄なので上記が推奨です。
要点は new B(); ではなく b= の部分です。
b=nullに限らず、変数bに何か新しく代入すれば、bがそれまで参照していたオブジェクトは参照を失うためアクセス不能になりガーベージコレクションの対象となります。
# 繰り返しますが、他に生きた参照がある場合は別です
回答ありがとうございます。
newでも解放に至ってくれるのですね。
newは空ではなくて、改めて作る、の印象で、メモリは残ってしまうものと思っていました。
確かにこれならdel後に呼び出し元から再度addをやってもbが空で呼べないは無いですね。
助かりました。感謝です。
No.1
- 回答日時:
del()って普通のメンバ関数ですよね。
間違って呼び出してバグになるだけなので止めた方が良いでしょう。解放処理を書くならデストラクタ~A()を定義してその中でしょうけど、単なるメモリ解放ならガーベージコレクタの領分なのでやる必要ないです。オブジェクトが開いていたファイルを閉じるとか、そういった処理を行ないます。あと他のオブジェクトの中まで触るような書き方をすると呼び出されるタイミングとか順序の問題でバグの原因となりかねないので余計な処理は書かない方が良いです。
ガーベージコレクタがある言語においてオブジェクトはプログラムからアクセスする手段がなくなるとガーベージコレクションの対象となります。質問の例だとクラスAのオブジェクトへのリンクをクリアした時点でその配下にあるb,c,sDataの全オブジェクトが回収対象になりそのうち回収されるでしょう。
# 他に生きた参照がある場合は別です
回答ありがとうございます。
GCでどうにかなるものなのですね。
del()については、呼び出し元任意でデータ削除を行いたいのです。
また、呼び出し元はクラスAのインスタンス破棄をしないため、デストラクタでは難しいのです。
ですので、例のコードが甘かったのですが、クラスAではコンストラクタを辞め、b.add前に「if(b == null) b = new B();」を追加のイメージになります。
ちなみに、del側はb=nullでGCによるメモリ解放はされますか?newをするのはメモリ解放に繋がらない考えでいます。認識違いでしたらすみません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java final 1 2022/06/10 22:49
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# クラスのメンバ変数を基準に並べ替えをしたい 5 2022/12/25 17:40
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- Java リレーションエンティティクラスとは何ですか? 2 2023/02/10 00:02
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# panel内のコントロールの使...
-
VB6では、Applicationは未定義...
-
Excel2003VBAからIE64bitを制御
-
クラスの設定について
-
ADODB.Connectionはインターフ...
-
VBA チェックボックスをオーバ...
-
一クラス何ステップ以上で読む...
-
任意の解像度のメモリデバイス...
-
VB6.0の関数をC++で使いたい
-
コンストラクタについて
-
c# Equalsメソッドについて
-
VisualStudio2005
-
【VC++】クラスの追加方法について
-
ダイアログ表示時にチェックボ...
-
C++でのDirectXプログラミング...
-
正規表現 [^/]+ の意味を教えて
-
Visual studio express 2013 ...
-
クラスプロジェクトのデバッグ
-
MFC VC++ 6.0 使用
-
Serialize で困ってます!!
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
オブジェクト型の変数が定義さ...
-
C# panel内のコントロールの使...
-
delete演算子によるメモリ解放...
-
CreateObjectとはどういう意味...
-
関数で値渡しと参照渡しではど...
-
ボタンを押すとラベルの文字を...
-
オブジェクトをどこでdisposeす...
-
クラス内にWin32APIのコールバ...
-
コンストラクタ内でのthisポインタ
-
【VC++6.0(MFC)】「Out of memo...
-
C#でのUNZIP32.DLLの利用方法が...
-
SetとNothingの存在意味?
-
一時オブジェクト?の生存期間
-
「R = ActiveCell」がエラーに...
-
最小化したフォームを元に戻す
-
DataGridViewがクラッシュする
-
クラス?オブジェクト?インス...
-
メモリ解放について、ご教授く...
-
メモリリークが発生するのはど...
-
UMLでの「オブジェクト」と「イ...
おすすめ情報