- PR -

Finalizeメソッドっていったい

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2005/03/12
投稿数: 148
投稿日時: 2005-03-25 20:12
私は、C++でプログラミングしていてJavaやC#は言語の一部しか知りません。
前々から思っていたんですが、Finalizeメソッドっ利用価値低いなぁ。
とりあえず使えないって覚えておいたほうがいいみたい。

ここで重要な処理をさせるのってまずいですよね。
呼ばれないかもしないし。

GCとか便利そうだとは思っているのですが、
Finalizeって不便というかいらないというか、Javaの真似?
C#ならもっと便利なもの作ってくれればいいのに。
Disposeも自動じゃないし。

デストラクタみたいなものがなくて不便なことはないのでしょうか。

追記
説明不足ですみません。
上記は『C++のデストラクタみたいなものがなくて』です。

[ メッセージ編集済み 編集者: 未記入 編集日時 2005-03-26 05:05 ]
猫山みやお
大ベテラン
会議室デビュー日: 2004/09/09
投稿数: 119
投稿日時: 2005-03-25 21:49
釣り?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-03-25 21:50
 C#にFinalizeメソッドってありました?C#はデストラクタですよ?
引用:

Finalize メソッドより:
[C#] C# では、ファイナライザはデストラクタ構文で表現されます。



 それでこれは、使えないのではなく、たいていの場合、使わなくて(明示的にコールしなくて)よいのです。C++の場合、newでアロケートしたメモリをdeleteで解放し、このときにデストラクタが呼ばれます。明示的に呼ばなくても、呼ばれます(というか、ふつう明示的には呼ばない)よね。同じです。ガベージコレクタが、。ガベージをコレクトするときに呼ばれます。そして、Disposeメソッドも、ここで呼ばれます。
 これは補足が必要。IDisposeインタフェースを実装するクラスは、デストラクタ(VB.NETではFinalizeメソッド)でIDispose.Disposeメソッドをコールするようにコーディングすることを求められています。このようにコーディングしてあれば、デストラクタからDisposeメソッドがコールされます。

 なので、デストラクタは存在するので、不便ではありません。


# 釣られた?

[ メッセージ編集済み 編集者: Jitta 編集日時 2005-03-25 21:50 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-03-25 22:29
C++のHevyユーザーにとっては、確かにFinalizeやDisposeは使いにくし貧弱に感じますね。C++ならAutoPtr等を利用すれば、スコープから外れた時点で直ちにデストラクタが呼び出されリソースが自動的に開放されてました。C#では、わざわざDisposeメソッドを呼び出してリソースを開放するなんて、退化にすら思えます。以前なら自動的に開放されていたものを、わざわざ明示的に開放させるなんて、何のためのGCなのやら。

#と、あおってみる?

とはいえこれはGCを実現する上で必ず突き当たるジレンマなんですよね。現実と理想の狭間で妥協した結果、このような仕様に落ち着いているのです。十分に現実的な妥協点だと私は思っていますけどね。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-03-25 22:42
引用:

甕星さんの書き込み (2005-03-25 22:29) より:
C#では、わざわざDisposeメソッドを呼び出してリソースを開放するなんて、退化にすら思えます。以前なら自動的に開放されていたものを、わざわざ明示的に開放させるなんて、何のためのGCなのやら。


 Disposeは、レガシーなリソース、アンマネージリソースを扱うときだけ、使用します。マネージリソースは、ガベージコレクタが管理しますから、わざわざ明示的に解放させる必要はありません。

 たとえば、Objectクラスのインスタンス…は極端だから、stringクラスやStringBuilderクラスのインスタンスは、Disposeする必要がありません。必要がないので、IDisposeインタフェースは実装されていません。
_________________
未記入
大ベテラン
会議室デビュー日: 2005/03/12
投稿数: 148
投稿日時: 2005-03-26 04:22
そうそう、甕星さんの発言にあるようなことです。
# 投稿日時: 2005-03-25 22:29
# この掲示板って、特定の発言をさすときって、投稿日時か、
# 自分で何番目の発言かかぞえるしかないの?

関連でJavaですが、
件名:FileInputStreamのcloseし忘れは、メモリーリーク?
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=16972&forum=12&4
の投稿日時: 2004-11-29 14:44 5番目

自分が使用したオブジェクトにcloseのような意味を持つメソッドがあるのならば、プログラマが忘れずにfinallyで呼び出すようにしたほうがいいということになる。
# 新しい言語なんだから便利になって欲しいけど。
# ファイルクローズをすぐに行わなくても困らないことが多いのでしょうけど。
# using(){}をデフォルトにしろよって思ってしまう。

実際は余り苦にならないとか余り問題にはならないってことでしょうか。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2005-03-27 21:47
(確定的)デストラクタがないってのはGCの動作上仕方ないことと割り切ってますね。未記入さんのいいたいことも分かるのですけど。

これを実現するには参照カウント式や所有権式がお手軽なのですけど、循環参照を解決できなかったり、所有権を意識しなきゃいけなかったり。開放動作をGCのみにする関係上どのような例外も認められないですし。

それを実現した現状の方式だと走査が必要で、確定的に破棄タイミングを判断できないんですよね…。だから必要なところはIDisposableやらusingやらで補ってますし、これからも補強されていくと思います。そして、なければないで設計を工夫する余地はありますしね。

その上で、こうすることによって得られたメリットが大きいです。まぁ、それを得るためにその部分で妥協したといったところでしょうか。

#と、気になったのですが。
#Jittaさん
#>ガベージをコレクトするときに呼ばれます。そして、Disposeメソッドも、ここで呼ば
#>れます。
#GC中ではなくてGC時にマーキングされてファイナライザスレッドが起動するんじゃな
#かったでしたっけ?
未記入
大ベテラン
会議室デビュー日: 2005/03/12
投稿数: 148
投稿日時: 2005-03-28 07:47
なるほど判りました。
実際にGCしてみないと未だ参照されているかもしれないから、自動でDisposeを呼ぶ訳にはいかない。ということで仕方ないということか。

スキルアップ/キャリアアップ(JOB@IT)