C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[29]: コントロール・フォントスタイル変更時のFont解放について [1]


(過去ログ 78 を表示中)

[トピック内 64 記事 (21 - 40 表示)]  << 0 | 1 | 2 | 3 >>

■46048 / inTopicNo.21)  Re[11]: コントロール・フォントスタイル変更時のFont解放について
  
□投稿者/ たくボン (340回)-(2010/01/23(Sat) 23:08:23)
No46042 (なちゃ さん) に返信
> ■No46041 (たくボン さん) に返信
>>■No46016 (なちゃ さん) に返信
> >>■No45950 (たくボン さん) に返信
> >>プロパティを「リセット」すると、コンテナと同一のインスタンスになったりします。
> >>※リセットした場合はDisposeしてはだめですし、同じフォントを設定した場合はDisposeする必要があることになります。
>>
>>http://msdn.microsoft.com/ja-jp/magazine/bb985010.aspx
>>http://msdn.microsoft.com/ja-jp/library/b1yfkh5e(VS.80).aspx
>>http://msdn.microsoft.com/ja-jp/library/system.drawing.font.dispose(VS.80).aspx
>>フォントのリソースが解放されるタイミングはいつかな?
>
> いまいち何が言いたいのか意図がよく分かりません。
> 私が書いたことのどの部分に対して、何を言いたいのかはっきり書いてもらえないでしょうか?
>
> 私が書いた
> >>※リセットした場合はDisposeしてはだめですし、同じフォントを設定した場合はDisposeする必要があることになります。
> は、
> もしデザイナ上でリセットした場合はコンテナと同一のFormインスタンスが設定されているので、コントロール側で不要になっても勝手にDisposeなんか実行してはいけないし(コンテナ側ではまだ使用中)、
> リセットではなく同じフォントを設定したのなら、別インスタンスなのでコントロール側で不要になったらDisposeを実行しないといけない(コンテナ側では使用していない)、
> でもこんな風にデザイナでの操作で変わってしまうような動きなので、自分で作るプログラムでもきちんと管理できていないことが多いだろう、
> だから、フォントを変える時に(必要な場合のみ)Disposeを呼ぶというやり方は現実的にあまり安全ではないだろう
> ということです。

安全ではない?本当に?

> nullの代入は実質的には動作に影響はない(動作は変わりますが最終結果は変わらない)のでおいとくとして、
おいておくんだ。確かに最終結果は変わらないね。

> Disposeを呼べば、その時点でradioButtonAに設定されていたFontの(ネイティブな)リソースが解放されて、そのうえでSuppressFinalizeによりFinalize対象から外されます。
radioButtonA.Fontは外れるよね。これで次回のGCでは一応このFontがガベージ対象になるかもしれないって訳だ。

> ※もし、FontのインスタンスがコンテナのFontと同一のものなら、後で問題が発生する危険があるでしょう。
どんな問題だろう?リソースが解放されてしまう危険?

> Disposeを呼ばなければ、そのあとの別のフォントの代入によって参照が外れますので、その時点でGC「対象」になるでしょう。
確かにGC対象にはなるけどDisposeを明示的に呼ぶ場合と、呼ばなかった場合はFinalizeの動作が変わってこない?

> 次のGC時にファイナライズ対象になり、そのうちファイナライざスレッドでリソースが解放され、さらにその次のGC時にメモリ回収されるでしょう。
さて、ここで問題。ファイナライザメソッドが呼び出されるのはどのタイミングか?
ファイナライザが回収すべき(Finalizeメソッド)は、どこで管理されてて、いつ登録されるのか?

> ※もし、FontのインスタンスがコンテナのFontと同一のものなら、何もしないのと実質変わりません(コンテナからの参照が生きているため、GC対象にはならない)。
一応解ってるみたいだけど。


MSがGCを採用した背景には、ガベージで管理するメモリはピンキリのプログラマがいるから、そいつらなんかにメモリの管理なんかまかせてられないってのがあるのは周知の事実。(へっぽこプログラマのせいでOSのせいにされちゃかなわないから)

そこでClose、DisposeとFinalizeメソッドを用意したんだけど、これだけでも不安は残る。特にStringクラスに代表されるような頻繁に可変長になる領域や同一リソースの重複はGCにとって、あまり歓迎されるものでもない。これはWin32の頃からAtomとかで色々してたから、.NETでも同じようなしくみは用意してると思う(でないとわざわざStrngとStringBuilderを分けてないはず)

さらに言えば、システムで用意しているSystemColorやSystemBrushesのようなオブジェクトはプログラマに公開してリソースの節約を図りたいけど、Disposeされる危険もある。クラス設計者はDisposeが何度呼ばれても大丈夫なように設計してるはずだろうし、プログラマがDisposeを呼び出してくれることを期待してもいけない。

だからファイナライザとFリーチャブルキューの機能を設けて、参照されているオブジェクトの保護もしてるってこと。

Dsiposeしない場合は、不要なオブジェクトとマーキングされて、オブジェクトの回収の段階で完全キューからFリーチャブルキューを参照。FontオブジェクトはFinalizeを実装してるから、Fリーチャブルキューに入れて次回のGCで最終的なゴミと判断してFinalize。


> このように自分でプログラムを作成している時でも、この辺りのプロパティのインスタンスがどうなっているかは
> 結構分かりにくかったり、予想と違う動作をしていたりもしますので、はっきりいってあまりきちんと管理できて
> いないことの方が多いように思います。

まったくその通り。
管理ができないならGCにまかせておけばいいと思うよ。

そのためのウルトラマンだし。

下手にDisposeとFinalizeを書かれてたりしたら、悩む材料なだけだし(ひどく言えばバグのもとにもなる。今は内部的にどうなったかわからんけどVS2005の暗黙的なFormとかは、この手の問題を抱えてたから、GCされる時にDisposeしてたりしてたら実際バグる時もあったし。この手のバグはGCと絡むから追跡しにくいバグだし、設計がちゃんとしてれば問題なかったはず。)

これくらい言えばわかってもらえたかな?

わからなかったら
selectedFont = new Font
だけでいいと思う。メモリ管理はGCに任せておけばOK(そのためのGCだし)
引用返信 編集キー/
■46050 / inTopicNo.22)  Re[12]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (371回)-(2010/01/24(Sun) 01:10:38)
No46048 (たくボン さん) に返信
>>でもこんな風にデザイナでの操作で変わってしまうような動きなので、自分で作るプログラムでもきちんと管理できていないことが多いだろう、
>>だから、フォントを変える時に(必要な場合のみ)Disposeを呼ぶというやり方は現実的にあまり安全ではないだろう
>>ということです。
>
> 安全ではない?本当に?

思わせぶりな書き方でなくて、何を言いたいのかはっきり書いていただきたいんですけどねー

現実には管理(把握)できていないことが多いと思われるからあまり安全ではないだろう、といっているのですが。
現実に、きちんと把握できている人ばかりなら別に何も言いません。
※一般的にそうではないだろうと私は思っているということです。

それとも別の意味で書いてますか?
安全ではないと言っている中身の話なら、もしFontのインスタンスがコンテナのものと同一なら、まだ使用中のFontインスタンスをDisposeすることになるので、普通に考えてこれは安全とは言えないということです。
※例えば、アンビエントプロパティの動作が効いていて、コンテナのFontインスタンスが共有されている場合

>>nullの代入は実質的には動作に影響はない(動作は変わりますが最終結果は変わらない)のでおいとくとして、
> おいておくんだ。確かに最終結果は変わらないね。

ここの記述が必要なら、そう言ってください。
次の瞬間に別のインスタンスが設定されるだけなので、特に書かなかったですが、この時点でGC「対象」になりますね。
※まあひょっとするとnull設定の時点で、内部処理では結構いろんな動作をしているかもしれませんね。
で次のGCで回収されますね。
Disposeを呼んでいるので、Finalizeは実行されません。

あるいは、また何か別のことが言いたかったですか?

>>Disposeを呼べば、その時点でradioButtonAに設定されていたFontの(ネイティブな)リソースが解放されて、そのうえでSuppressFinalizeによりFinalize対象から外されます。
> radioButtonA.Fontは外れるよね。これで次回のGCでは一応このFontがガベージ対象になるかもしれないって訳だ。

GC対象になるのはそのあと別のインスタンスを設定して参照が外れた時点です。
Disposeだけ(この時点)ではGC対象にはなってませんが、というかDispose呼んだかどうかはGC対象になるかどうかとは直接関係ありませんが、何か違う意味で書いてますか?

>>※もし、FontのインスタンスがコンテナのFontと同一のものなら、後で問題が発生する危険があるでしょう。
> どんな問題だろう?リソースが解放されてしまう危険?

上でも書きましたが、コンテナのFontはまだ使用中ですから、それと同一のインスタンスをDisposeするのは普通危険に思います。

>>Disposeを呼ばなければ、そのあとの別のフォントの代入によって参照が外れますので、その時点でGC「対象」になるでしょう。
> 確かにGC対象にはなるけどDisposeを明示的に呼ぶ場合と、呼ばなかった場合はFinalizeの動作が変わってこない?

そもそもDisposeを呼んでいればFinalizeは実行されませんが、そういうことではなくて?

>>次のGC時にファイナライズ対象になり、そのうちファイナライざスレッドでリソースが解放され、さらにその次のGC時にメモリ回収されるでしょう。
> さて、ここで問題。ファイナライザメソッドが呼び出されるのはどのタイミングか?
> ファイナライザが回収すべき(Finalizeメソッド)は、どこで管理されてて、いつ登録されるのか?
>
>>※もし、FontのインスタンスがコンテナのFontと同一のものなら、何もしないのと実質変わりません(コンテナからの参照が生きているため、GC対象にはならない)。
> 一応解ってるみたいだけど。

別にどう思われようとかまいませんが、どこかで私がおかしなことを書いていてこいつ分かってないなとか思ったのでしたら、どこがおかしかったかはっきり書いてくださいな。

これ以降はさらに「私に対しては」何を言いたいのかわかりません。
どう反応していいのか分からないのでとりあえずは割愛します。

> これくらい言えばわかってもらえたかな?
>
> わからなかったら
> selectedFont = new Font
> だけでいいと思う。メモリ管理はGCに任せておけばOK(そのためのGCだし)

はっきり言いたいことを書いてください。
※メモリ管理って、メモリ管理じゃなくてメモリ以外のリソースの管理の意味ですか?

私は最初から、現実的にはFontとかのインスタンスがどうなっているか完全に自分で把握できていない人の方が多いと思うので、現実的にDisposeはやめといた方が無難だということを言ってます。
別に、俺は完全に管理している、という人しか関わらないなら好きにすればいいですし、それに対してどうこう言うつもりもありません。

ただ、大量に生成するのであれば別ですが、そうでない場合や、単にインスタンスをキャッシュしておいて切り替えるだけで済む場合なら、わざわざ明示的にDisposeしなくてもいいレベルのことではないかとは思っています。
※万一管理ミスでおかしな不具合になるくらいなら、わずかなリソースの無駄の方がダメージが小さいだろうという、妥協です。

引用返信 編集キー/
■46052 / inTopicNo.23)  Re[13]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (373回)-(2010/01/24(Sun) 01:34:33)
No46050 (なちゃ さん) に返信
> Disposeだけ(この時点)ではGC対象にはなってませんが、というかDispose呼んだかどうかはGC対象になるかどうかとは直接関係ありませんが、何か違う意味で書いてますか?

読み方と文脈によってはおかしくとられる可能性もあるかもしれないと思ったので一応補足。
>というかDispose呼んだかどうかはGC対象になるかどうかとは直接関係ありませんが、
ここでのGC対象とは、あくまでコレクションの対象という意味で書いてます。
メモリ回収という意味では書いてませんので、あしからず。

Dispose呼んでない場合は一回回収された後でファイナライズ対象になり、ファイナライズが終わるまではまたいったん回収対象では無くなって、ファイナライズ完了後に再度回収対象になって回収された後、最後にメモリ回収という流れになりますが、
上で書いている「GC対象」はひとまず一回目の回収対象という意味で書いてます。

引用返信 編集キー/
■46053 / inTopicNo.24)  Re[14]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (374回)-(2010/01/24(Sun) 01:46:24)
>> だけでいいと思う。メモリ管理はGCに任せておけばOK(そのためのGCだし)

>はっきり言いたいことを書いてください。
>※メモリ管理って、メモリ管理じゃなくてメモリ以外のリソースの管理の意味ですか?

んーこれもおかしいなー。
GCというか、メモリ管理は(不要な参照を持ち続けないという点を除けば)GCに任せる以外ないですが(というか、不要な参照を持ち続けないように注意する)、
言いたかったのはメモリ以外のリソース管理をファイナライザに任せておくっていうことですか?

私は、今回のようなFontなどに関しては、大量にインスタンスを作るのでなければ、現実的にはファイナライザ任せでもいいレベルだと思っていますが、
もちろんリソースの種類によってはそんなことは思っていませんし、分かっている、分かっていないのレベルではなくて、ちゃんと理解して自分で解放しなければならないと思っていますよ。
負荷の大きいリソース、数が限られたリソース、自分で解放しないとそもそもGC対象にもならないようなリソース、ファイルのように開いたままでは困るリソース、こういったものですね。

引用返信 編集キー/
■46054 / inTopicNo.25)  Re[15]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (375回)-(2010/01/24(Sun) 02:31:28)
>だからファイナライザとFリーチャブルキューの機能を設けて、参照されているオブジェクトの保護もしてるってこと。

これはあんまり一般的な見方じゃないんじゃないかと。
単に、GCだけでは面倒が見れないリソースを最終的に確実に開放できるようにするために、ファイナラーゼーションという機能が提供されているというのが普通な気がしますけどね。
※まあ、そういう言い方もできなくはないかもしれませんが、どっちかっていうと普通はリソースの確実な解放のため、でしょう。

>Dsiposeしない場合は、不要なオブジェクトとマーキングされて、オブジェクトの回収の段階で完全キューからFリーチャブルキューを参照。FontオブジェクトはFinalizeを実装してるから、Fリーチャブルキューに入れて次回のGCで最終的なゴミと判断してFinalize。

単にラフに書いただけなのかわざとなのかちょっとわかりませんが、ファイナライゼーションキュー(完全キューって言い方はっ初めて聞いたような気がしなくもない、日本語訳によっては確かにあるかもしれないが)に登録されるのはFizalizeメソッドをオーバーライドしているクラスのインスタンスだけです(基本的には、インスタンス化時に登録される)。

「完全キューからFリーチャブルキューを参照」の意味がよくわかりませんが、GC時にはファイナライゼーションキューからFリーチャブルキューにオブジェクトが移動されます。
このときに、SuppressFinalize呼び出し済みのオブジェクトだった場合は除外されます(Finalizeメソッドを実装しているクラスは、通常Dispose時にSuppressFinalizeして不要なファイナライズ呼び出しを避ける)。

まあ細かい話ですが一応念のため。

引用返信 編集キー/
■46055 / inTopicNo.26)  Re[16]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (376回)-(2010/01/24(Sun) 02:46:07)
一応ついでなのでこれも、

>Fリーチャブルキューに入れて次回のGCで最終的なゴミと判断してFinalize。

Fリーチャブルキューに入ったオブジェクトは、その時点からファイザライゼーション専用のスレッドが順にFinalizeを呼び出していきます。
Finalizeの実行が完了したものはその時点で参照が外されるため、次のGCで今度こそ本当に回収されます。
※「次回のGCで最終的なゴミと判断してFinalize」という動きではありません、念のため。

まあ普通にアプリケーションを実装する分にこんな細かいことを意識する必要はそんなにないと思いますけどね。
Finalizeを実装したオブジェクトはすぐには回収できない、ということくらいは知っておいた方がいいとは思いますが。
ただ現実には、こういうのもみんな知っとけというのは難しい気がします、というか現実には知らない人の方が多いでしょう。
引用返信 編集キー/
■46056 / inTopicNo.27)  Re[13]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (341回)-(2010/01/24(Sun) 10:51:32)
No46050 (なちゃ さん) に返信
> ■No46048 (たくボン さん) に返信
> Disposeを呼んでいるので、Finalizeは実行されません。

色々詳しく書いてくれたみたいだけど、こんなGCなら俺は使わない。
このへんなんかちょっとサンプル作ればすぐ調べれると思う。

日本人頭いい人多いから、教科書に書かれたことだけ鵜呑みにして自分で調べようとしない(というか考えない人が多い)から、これ以上議論しても無駄かも。(俺から見たら同じ答えしか返ってこないからつまらんけど)

> 単にラフに書いただけなのかわざとなのかちょっとわかりませんが、ファイナライゼーションキュー(完全キューって言い方はっ初めて聞いたような気がしなくもない、日本語訳によっては確かにあるかもしれないが)に登録されるのはFizalizeメソッドをオーバーライドしているクラスのインスタンスだけです(基本的には、インスタンス化時に登録される)。

上げ足取られた(笑)
DAOのことを「ダオ」って言う人に突っ込み入れるタイプの人間かな?

翻訳の違いで言い方は変わると思うけど、.NET出始めの頃、MS公式のソースにそう翻訳してるんだからいいと思うけどな。(それともふぁいならいぜーしょんきゅーって書かないと試験では落ちますか?)
引用返信 編集キー/
■46057 / inTopicNo.28)  Re[14]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (377回)-(2010/01/24(Sun) 11:54:33)
一応書いておこう。
今携帯ですので細かくは書けませんし、文がおかしくなってしまうかもしれませんが。

まず最初に、完全キューというのは普通に聞いたことない言い方だったので思ったことを書いただけです。
ファイナライゼーションキューの意味で間違いないですよね?
て念を押したかったというのもあります。
揚げ足と思われたらすみませんが、違和感があったので素直に書いただけです。
# 完全キューだと、ちょっと意味が通らないため
ただし、訳によってはとあえて書いたのは、どこかにそういう記述があったかも知れないと思ったからで、
それならたくボンさんは何も悪くない(悪いというのは本当に悪いという意味ではなくて、ちょっといい言葉が浮かびませんが、仕方ない?とか?)
ということを一応言いたくて、むしろ擁護の方向で書いたわけなんですが、書き方が悪かったようです。

あと、今回は意味が通らなくて違和感があったから書いたのであって、
別に一々揚げ足をとるつもりはありませんよ。
誤解を招きそうな書き方なんかは指摘したりすることはありますが。


でこれはこれとして、Disposeを呼んだらFinalizeが呼ばれないのは
仕様上も現実の動きも事実なんですが、一体何が気に入らないんでしょうか?
※これは、Fontクラスの話、つまりDisposeでSuppressFinalizeを呼んでるクラスの話ですよ、文脈上明らかですが、念のため。

Finalizeの実行を抑制できないなら、SuppressFinalizeの意味が無いでしょう。


いちいち教科書とか嫌みっぽく書かれてしまいますが、
何を見てそう思われるのかよく分かりません。

まあ、試すのが手間な部分は、プログラミング.NET Frameworkとかの書籍の記述や、
MSDNマガジンの記事や、Technetマガジンの記事など、
信用出来ると思っている書籍や記事の記述は信用していますけどね。
疑問を感じたらそれなりに確認や調査はします。
ただまあ、どこまでも追及するようなことはないですけどね、
自分にとって特に興味深い内容とか特に重要な内容でなければ。

引用返信 編集キー/
■46058 / inTopicNo.29)  Re[15]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (378回)-(2010/01/24(Sun) 12:07:20)
それから、同じ答えで意味ないとのことですが…
事実は事実であって書き方変えても中身は結局同じ内容なる(もっと詳細にとか詳しさのレベルは変わるとしても)と思いますが、何を求めてますか?

私は基本的にたくボンさんが聞くからそれに答えてるだけです。
聞いてる意図がいまいち分からないからはっきり書いてくれと何度も言ってますが。

もっと違う答えを求めてるなら、何度も言ってますがはっきり書いてください。

引用返信 編集キー/
■46061 / inTopicNo.30)  Re[15]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (342回)-(2010/01/24(Sun) 14:10:07)
No46057 (なちゃ さん) に返信
> 一応書いておこう。
> それならたくボンさんは何も悪くない(悪いというのは本当に悪いという意味ではなくて、ちょっといい言葉が浮かびませんが、仕方ない?とか?)

おいおい、どんだけ上から目線やねん。
お前はそんなに偉いの?

俺は別に聞きたいことなんかないんで、そこは勘違いしなくてOK。
引用返信 編集キー/
■46064 / inTopicNo.31)  Re[16]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ Jitta on the way (532回)-(2010/01/25(Mon) 07:33:42)
No46061 (たくボン さん) に返信
> ■No46057 (なちゃ さん) に返信
>>一応書いておこう。
>>それならたくボンさんは何も悪くない(悪いというのは本当に悪いという意味ではなくて、ちょっといい言葉が浮かびませんが、仕方ない?とか?)
>
> おいおい、どんだけ上から目線やねん。
> お前はそんなに偉いの?
>
> 俺は別に聞きたいことなんかないんで、そこは勘違いしなくてOK。

なんか、付いていけなくなったから脇道にそらしたように見える。


のぞんでないらしから、これにておしまい>なちゃさん
解決済み
引用返信 編集キー/
■46069 / inTopicNo.32)  Re[17]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (343回)-(2010/01/25(Mon) 12:59:05)
No46064 (Jitta on the way さん) に返信
> ■No46061 (たくボン さん) に返信
>>■No46057 (なちゃ さん) に返信
> >>一応書いておこう。
> >>それならたくボンさんは何も悪くない(悪いというのは本当に悪いという意味ではなくて、ちょっといい言葉が浮かびませんが、仕方ない?とか?)
>>
>>おいおい、どんだけ上から目線やねん。
>>お前はそんなに偉いの?
>>
>>俺は別に聞きたいことなんかないんで、そこは勘違いしなくてOK。
>
> なんか、付いていけなくなったから脇道にそらしたように見える。

そうだねぇ。
俺頭悪いから付いていけないみたいだから教えてください。


Label1.Font = null;

とした時の、System.Windows.Forms.Control.GetParentFont + 0x14〜0x17の

00000014 xor eax,eax
00000016 pop esi
00000017 pop ebp
00000018 ret

は何してるのか教えてください。
esi, eaxが何指してて、何を返却してるのかとか。

PropertyS tore.LocateObjectEntryやPropertyS tore.GetObjectは長いから省略してるから、重要なレジスタとアセンブリの位置、意味を書いてくれたら助かります。

もし、わかるならSystem.Windows.Forms.Control.get_ParentInternal + 0x35くらいから説明してもらえると助かるなぁ。(この辺から公式の資料も無かったりしてレジスタの値がピンとこない)

なちゃさんもjittaさんも、かなり詳しいみたいだから、わかりやすく教えてくれると助かるなぁ。

[S tore]は使えないみたいだから、空白省略してくださいね。
引用返信 編集キー/
■46071 / inTopicNo.33)  Re[18]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (344回)-(2010/01/25(Mon) 13:19:22)
2010/01/25(Mon) 13:39:25 編集(投稿者)

No46069 (たくボン さん) に返信
> ■No46064 (Jitta on the way さん) に返信
>>■No46061 (たくボン さん) に返信
> >>■No46057 (なちゃ さん) に返信
>>なんか、付いていけなくなったから脇道にそらしたように見える。

上が終わったら、Label1.Font.Disposeの話しようね。
ここではなちゃさんが自慢げに言ってたファイナライズの処理やアンビエントプロパティも絡んでくるから、できればなちゃさんに教えてもらいたいな。

追記:この話題はあくまでもCGと.NETの動作を調べるための議論だから、MSの逆アセンブルのライセンスには違反してないと思うけど、問題あるようなら別の方法を考えます。
引用返信 編集キー/
■46088 / inTopicNo.34)  Re[19]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ ななし (8回)-(2010/01/25(Mon) 21:35:23)
レジスタの話より、公開されているソースをみて議論した方が早そうに思います。
知らなかったんですが、フォントまわりって単純じゃないですね。
(私にはたくボンさんの論点がずっと解らなかったのですが、このあたりの話でしょうか)

実験コードです。

// 引数が同じフォントを2つ作成。
var font1 = new Font("MS ゴシック", 20);
var font2 = new Font("MS ゴシック", 20);
// 同じコントロールに順次設定。
label1.Font = font1;
label1.Font = font2;
// 調べごと。
var f1 = font1.Equals(font2); // …true
var f2 = object.ReferenceEquals(font1, font2); // …false
var f3 = object.ReferenceEquals(label1.Font, font1); // …true
var f4 = object.ReferenceEquals(label1.Font, font2); // …false
// font1.Dispose();
// var height = label1.Font.GetHeight();

上記の場合に限っては、おかしな話ですけど、厳密には font2 を Dispose する必要があります。
素直に Dispose するようなコード(コメントを有効)を書いちゃうと、例外につながります。
(font2 の設定の前で label1.Font.Dispose をしちゃうのも駄目です。)

これは、Font プロパティが、ごく一般的な実装とは違うためにそのような動作になります。
その実装の前提として、フォントが GDI+ によって同じとみなされる単位で参照カウンタで管理されていることがあるようです。
そのためか(リソースの枯渇に直結しないためか)、上記結果からも、フレームワークとしてはフォントのインスタンスは重要視していないように感じられます。
たくさんフォントを作成してもリソース不足にならなかった理由は、ここにあったようです。
(GDI+ での参照カウンタの話は、フレームワークのソースのコメントに書いてありました。GDI+ の詳細について検索してみたのですが、わかりませんでした。)

最初の私の返信ですが、内容は間違ってないと思いますが、一般的なオブジェクトや普通のプロパティを前提にしていました。けど実際はもう少しややこしい背景があったんですね。
解決済み
引用返信 編集キー/
■46090 / inTopicNo.35)  Re[20]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (380回)-(2010/01/25(Mon) 23:30:38)
No46088 (ななし さん) に返信
> // 引数が同じフォントを2つ作成。
> var font1 = new Font("MS ゴシック", 20);
> var font2 = new Font("MS ゴシック", 20);
> // 同じコントロールに順次設定。
> label1.Font = font1;
> label1.Font = font2;
> // 調べごと。
> var f1 = font1.Equals(font2); // …true
> var f2 = object.ReferenceEquals(font1, font2); // …false
> var f3 = object.ReferenceEquals(label1.Font, font1); // …true
> var f4 = object.ReferenceEquals(label1.Font, font2); // …false
> // font1.Dispose();
> // var height = label1.Font.GetHeight();
>
> 上記の場合に限っては、おかしな話ですけど、厳密には font2 を Dispose する必要があります。
> 素直に Dispose するようなコード(コメントを有効)を書いちゃうと、例外につながります。
> (font2 の設定の前で label1.Font.Dispose をしちゃうのも駄目です。)

これがまたややこしくて、既に設定されているのと同じ内容のフォントが設定された場合はフォントは変化しないんですが、元々アンビエントプロパティで親(コンテナ)から継承している場合は設定しなおされるんですよね。

また、フォントのインスタンス自体が置き換えられていて、かつ元々のフォント(コンテナから継承された場合でも個別に持っていた場合でも)から変わった場合は、DisposeFontHandleなんていう如何にもそれらしいメソッドが呼ばれていて、
ぱっと見自動でリソースの解放をやってくれているようにも見えるんですよね。
※ただ、内部動作的にコンテナから継承している場合は結局最終的に開放のような処理は走らないと思われる。

これを見て一瞬、あれ、ひょっとしてDisposeはそもそも不要?と思ったんですが、これを呼んでもFontクラス内のハンドルらしきものは0になったりしていなかったため(Font.Disposeの場合は0になる)、やっぱり違うのかなーとか、この辺で追うのはあきらめてしまいました。
※DisposeFontHandle自体も中で条件によって動くため、どういうときに解放動作が起こるのかまでは未確認

もっと細かく調べたら、やっぱり実はフォントの変更時は元々Dispose不要ということもあるかもしれません。


> これは、Font プロパティが、ごく一般的な実装とは違うためにそのような動作になります。
> その実装の前提として、フォントが GDI+ によって同じとみなされる単位で参照カウンタで管理されていることがあるようです。
> そのためか(リソースの枯渇に直結しないためか)、上記結果からも、フレームワークとしてはフォントのインスタンスは重要視していないように感じられます。
これは確かにそんな感じに見えます。

引用返信 編集キー/
■46092 / inTopicNo.36)  Re[20]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (345回)-(2010/01/25(Mon) 23:40:55)
No46088 (ななし さん) に返信
> レジスタの話より、公開されているソースをみて議論した方が早そうに思います。
> 知らなかったんですが、フォントまわりって単純じゃないですね。
> (私にはたくボンさんの論点がずっと解らなかったのですが、このあたりの話でしょうか)
>
> 実験コードです。
> var f1 = font1.Equals(font2); // …true
> var f2 = object.ReferenceEquals(font1, font2); // …false
> var f3 = object.ReferenceEquals(label1.Font, font1); // …true
> var f4 = object.ReferenceEquals(label1.Font, font2); // …false

いや、こんな当たり前のことは分かってるつもりだから。

それより仕事から帰ってきて楽しみにしてたのにjittaさんとなちゃさんは何してるの?
早くスレが埋もれる前に、俺が納得できる形で説明して欲しいんだけど?

特にjittaさんは俺より凄い詳しいみたいだから、詳しく解説してね。

レジスタがどうとか、アプリケーションのメモリ空間がどうとかクラスの継承時のメタデータがどうとかの基礎はわかってるつもりだけど、初心者でも頑張って勉強しようと思う人がいるかもしれないから、その辺の資料も交えて説明してくれたら助かります。

俺も説明してくれれば頑張ってついていきますから。(ただし、裏付ける資料や何故そうなるかの根拠くらいは書いてね。)

当然技術者同士の話で、モノ言うてるんやろうから時間ないとか、放置とか、見てなかったとか言い訳はしないですよね?:-)
引用返信 編集キー/
■46093 / inTopicNo.37)  Re[21]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (346回)-(2010/01/26(Tue) 00:54:39)
No46090 (なちゃ さん) に返信
> これがまたややこしくて、既に設定されているのと同じ内容のフォントが設定された場合はフォントは変化しないんですが、元々アンビエントプロパティで親(コンテナ)から継承している場合は設定しなおされるんですよね。
>
> また、フォントのインスタンス自体が置き換えられていて、かつ元々のフォント(コンテナから継承された場合でも個別に持っていた場合でも)から変わった場合は、DisposeFontHandleなんていう如何にもそれらしいメソッドが呼ばれていて、
> ぱっと見自動でリソースの解放をやってくれているようにも見えるんですよね。
> ※ただ、内部動作的にコンテナから継承している場合は結局最終的に開放のような処理は走らないと思われる。

いや、思われるじゃなくてちゃんと説明してください。走るのか、走らないのか?またその根拠となる部分はどこなのか?

> これを見て一瞬、あれ、ひょっとしてDisposeはそもそも不要?と思ったんですが、これを呼んでもFontクラス内のハンドルらしきものは0になったりしていなかったため(Font.Disposeの場合は0になる)、やっぱり違うのかなーとか、この辺で追うのはあきらめてしまいました。
> ※DisposeFontHandle自体も中で条件によって動くため、どういうときに解放動作が起こるのかまでは未確認

なぜ未確認?
中途半端な回答で逃げるとかやめようや。技術者なら「ここがこうだからこう」って書いて教えてくださいね。

俺もVS2003の頃、.NETの継承時の不具合やADOのバインド周りでバグ見つけた時は、アセンブリレベルまで辿って、それからMSに質問してたからアセンブリで説明してくれても少しくらいはわかってるつもりなので、しっかり教えてください。

一応、全部こっちの予想通りの動作だったからインシデント消費になったことはないけど、質問と同時にアセンブリを添付して、「ここ」って書いておけばすぐ対応してくれてたし、ソースがどうとかヘルプがどうとかより、アセンブリの方が話早い場合もあるから。(そもそもヘルプや技術文書に書いてあることと違うから不具合なんだろうけど)

アセンブリの記述は、メソッド+オフセットで「ここからどうなる」とか書いてくれたらいいから、Dispose時のアンビエントプロパティの動作とGCの動作を詳しく教えてください。
引用返信 編集キー/
■46094 / inTopicNo.38)  Re[21]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ たくボン (347回)-(2010/01/26(Tue) 01:04:01)
2010/01/26(Tue) 01:35:25 編集(投稿者)

No46090 (なちゃ さん) に返信
> ■No46088 (ななし さん) に返信
> これがまたややこしくて、既に設定されているのと同じ内容のフォントが設定された場合はフォントは変化しないんですが、元々アンビエントプロパティで親(コンテナ)から継承している場合は設定しなおされるんですよね。
> これを見て一瞬、あれ、ひょっとしてDisposeはそもそも不要?と思ったんですが、これを呼んでもFontクラス内のハンドルらしきものは0になったりしていなかったため(Font.Disposeの場合は0になる)、やっぱり違うのかなーとか、この辺で追うのはあきらめてしまいました。

これは俺が最初の45932で書いてるから。
一応テスト用のソース書いて、Disposeしても問題ないと思ったから書いてるので、俺はここから先の話が聞きたいんだが?


追記:ついでに、そんとき問題ないと判断した時の検証コードも載せておきます(この時はまだアセンブリレベルでは判断してなかったけど)

If Object.ReferenceEquals(Me.Font, Me.Label1.Font) Then
Debug.Print("E")
Me.Label1.Font.Dispose()
Me.Label1.Font = Nothing
If Object.ReferenceEquals(Me.Font, Me.Label1.Font) Then
Debug.Print("E")
Else
Debug.Print("NE")
End If
Else
Debug.Print("NE")
End If

VBで書いてたから、45932で書く時はC#に書き直したけど一応問題ないと判断したので。

ところでjittaさんは何してるんかな?色々教えて欲しいんだけど:-)
引用返信 編集キー/
■46096 / inTopicNo.39)  Re[22]: コントロール・フォントスタイル変更時のFont解放について
□投稿者/ なちゃ (381回)-(2010/01/26(Tue) 02:11:22)
正直言ってもう返信しないかもしれません、私にとって無益なので。

No46093 (たくボン さん) に返信
> ■No46090 (なちゃ さん) に返信
>>ぱっと見自動でリソースの解放をやってくれているようにも見えるんですよね。
>>※ただ、内部動作的にコンテナから継承している場合は結局最終的に開放のような処理は走らないと思われる。
>
> いや、思われるじゃなくてちゃんと説明してください。走るのか、走らないのか?またその根拠となる部分はどこなのか?

でも聞きたいわけじゃないんでしょう?
私にとっては無駄なんですよね。
思われると書いたのは動作が推測で、普通に考えて間違いないとは思うけれども確認してなかったから断定を避けたんですよ。
でまあ一応確認してみましたが間違いないです。
D〜とP〜とキーのを見ればそのままですね。

>>これを見て一瞬、あれ、ひょっとしてDisposeはそもそも不要?と思ったんですが、これを呼んでもFontクラス内のハンドルらしきものは0になったりしていなかったため(Font.Disposeの場合は0になる)、やっぱり違うのかなーとか、この辺で追うのはあきらめてしまいました。
>>※DisposeFontHandle自体も中で条件によって動くため、どういうときに解放動作が起こるのかまでは未確認
>
> なぜ未確認?
> 中途半端な回答で逃げるとかやめようや。技術者なら「ここがこうだからこう」って書いて教えてくださいね。

私が書きたかった話の流れでは関係なさそうで、それ以上調べる気にならなかったからです。
そもそもDisposeを呼べばいいと書いたのはたくボンさんですからね、まあ自動解放はされないということなのだろう、ですね。
nullの代入に意味はあるのかと聞いた時には気にしなくていいということでしたしね。

> アセンブリの記述は、メソッド+オフセットで「ここからどうなる」とか書いてくれたらいいから、Dispose時のアンビエントプロパティの動作とGCの動作を詳しく教えてください。

なんでネイティブのコードで話を進めたいんですか?素朴な疑問ですが。
で、何を聞きたいのですか?せめて聞きたいことを具体的に書いてくださいな。
そもそもアンビエントプロパティを取得した後に、取得したインスタンスに対してDisposeなんですから、
>Dispose時のアンビエントプロパティの動作とGCの動作
これが何を聞きたいのかどういうことを言ってるのか意味が分かりません。

No46094 (たくボン さん) に返信
> 2010/01/26(Tue) 01:35:25 編集(投稿者)
>
> ■No46090 (なちゃ さん) に返信
>>■No46088 (ななし さん) に返信
>>これがまたややこしくて、既に設定されているのと同じ内容のフォントが設定された場合はフォントは変化しないんですが、元々アンビエントプロパティで親(コンテナ)から継承している場合は設定しなおされるんですよね。
>>これを見て一瞬、あれ、ひょっとしてDisposeはそもそも不要?と思ったんですが、これを呼んでもFontクラス内のハンドルらしきものは0になったりしていなかったため(Font.Disposeの場合は0になる)、やっぱり違うのかなーとか、この辺で追うのはあきらめてしまいました。
>
> これは俺が最初の45932で書いてるから。
> 一応テスト用のソース書いて、Disposeしても問題ないと思ったから書いてるので、俺はここから先の話が聞きたいんだが?

ここから先ってなんですか?
私が書いてるのは、これがアンビエントプロパティの動作でコンテナと同一のフォントだった場合など、状況によってはDisposeしちゃいけない場合があるから、一般にはしない方が無難じゃない?
ですが、「ここから先」とは何を意味していて今までの話とどういう関係なんでしょうか?
聞きたいと言われても「何を?」ですね、何度言ってるのかって感じですが…

> 追記:ついでに、そんとき問題ないと判断した時の検証コードも載せておきます(この時はまだアセンブリレベルでは判断してなかったけど)
>
> If Object.ReferenceEquals(Me.Font, Me.Label1.Font) Then
> Debug.Print("E")
> Me.Label1.Font.Dispose()
> Me.Label1.Font = Nothing
> If Object.ReferenceEquals(Me.Font, Me.Label1.Font) Then
> Debug.Print("E")
> Else
> Debug.Print("NE")
> End If
> Else
> Debug.Print("NE")
> End If
>
> VBで書いてたから、45932で書く時はC#に書き直したけど一応問題ないと判断したので。

これが何の検証になっていると思ってるんですか?
フォントを明示的に設定していない場合、つまりアンビエントプロパティの仕組みが働いている場合、
最初にMe.Fontを覚えておけば、最終的なMe.FontもMe.Label1.Fontも最初のインスタンスと同一であることが確認できるでしょう?
つまりまだ使用中のフォントをDisposeしてるわけで、普通に考えればまずいのでは?と思いますよね?
もちろん最後に別のフォントを代入しても、Me.Fontは最初のままですから同じです。

引用返信 編集キー/
■46104 / inTopicNo.40)  Re[23]: コントロール・フォントスタイル変更時のFont解放について
 
□投稿者/ たくボン (348回)-(2010/01/26(Tue) 11:02:14)
No46096 (なちゃ さん) に返信
> 正直言ってもう返信しないかもしれません、私にとって無益なので。

えぇ、お好きにどうぞ。
俺も正直飽きてきたし、自分なりの答えは見つけたから満足できたし。


> でも聞きたいわけじゃないんでしょう?

聞きたくなったのは本心!

上から目線の人がどれくらいのスキルで偉そうにしてるのか知りたかったから。
jittaって人は何も書いてこないからわからんが、「答えなかった」って言う事実だけはわかったのでいいわ。


> 私が書きたかった話の流れでは関係なさそうで、それ以上調べる気にならなかったからです。

本当に調べる気にならなかったのか、わからないのかそこは最後にはっきりして欲しかったなぁ。
こんな中途半端な言い訳で終わらせて、自分の中で納得できてる?


> なんでネイティブのコードで話を進めたいんですか?素朴な疑問ですが。

一言で言えばアセンブリは嘘言わないから。
技術文書にしても人の言うことでも、最後に信用できるのはアセンブリ。

もちろん技術文章は参考にはするけど、ソースレベルで問題なくてコードが期待する動作にならない場合や疑問に思うことはアセンブリで確認するのは定石でしょう。

不具合とかで最終アドレスしかわからないケースとかよくある話だし、結局最後頼りになるのはアセンブリ。
こういう場合はスタックとか潰してる場合が多いからアセンブリレベルで原因を特定したりするのは当たり前のことと思うけど?

今回は技術文書も少ない話をしてたつもりだから、アセンブリレベルで動作の話をするのは当たり前だと思うんだが?

逆にこっちが素朴な疑問だよ。


> ここから先ってなんですか?

■45932にも「気になってた」って書いてるけど、■45910のななしさんの書いている「oldFont は本当に自分が new したものかわかりません(少なくとも初回は違う)し、他で共有しているフォントである可能性もあるので、機械的に常に上記のように解放するのも危険です。」ってことについて話をしてたつもりなんだけど?

Fontのようなオブジェクトで、機械的に解放処理を入れるのは
・危険だから絶対にしてはいけないのか?
・わかってない普通のプログラマが間違って解放しても問題ないように設計されているのか?
・一般的にはしないだろうけど、動作が理解できているなら解放処理を書いても特に問題はないのか?
これのどれ?って話だから。




「学校ではこう習ったので私の言うことは間違いはありません!」
「あーそー」
引用返信 編集キー/

<前の20件 | 次の20件>
トピック内ページ移動 / << 0 | 1 | 2 | 3 >>

管理者用

- Child Tree -