質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

C#のデバッグやメモリの管理について理解を深めたい

解決済

回答 6

投稿

  • 評価
  • クリップ 2
  • VIEW 2,367

tkow

score 1225

お世話になっております.

独学でC#のコードを書くことが多く,一度ちゃんと言語仕様を理解しようと思い,日本語訳もあるのでEffectiveC#4.0を読むことにしました。
かなり難解だと思うことが多く, 半分くらいしか理解できていないと思っています。

ただ一回ざっと読んだ印象では逆に今まで自分の書いていたコードが恐ろしくなり, 読んでおいてよかったと思うことが沢山書いて合った気がします。
C#のコンパイラやメモリ管理およびその他の知識を拡充したいため何かオススメの書籍や情報源を教えていただけないでしょうか。

特に以下の項目を勉強したいです。

  • CLR
  • IL
  • IDE拡張
  • 逆アセンブル
  • デバッグ機能
  • ガベージコレクタ
  • 副作用
  • 共変性/反変性

今まで読んだ本は以下の通りです。

  • VisualC#パーフェクトマスター 2013

  • C#ショートプログラミング

  • C#によるマルチコアのための非同期/並列処理プログラミング

  • 究極のC#プログラミング~新スタイルによる実践的コーディング 

  • C#6.0 Cook Book(洋書)

特に参照消し忘れのようなバグに悩まされているため, メモリの動きがどのようになっているか見る方法や, 参照している変数の調べ方などデバッグに重点を置いた内容の情報を探しています。よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

+5

こんにちは。

特に参照消し忘れのようなバグに悩まされている

これがもし参照型変数を代入して、コピーのつもりが共有してしまったバグでしたら、十分な対処方法はないような気がしてます。

軽減するために、C言語のポインタをきっちりマスターすることは有用と思います。特に構造体へのポインタ変数はC#のクラスの参照型変数とそこそこ近いです。多くの人が躓くポイントですが、高速なプログラムを書くためには必須スキルと思います。
そして、C#やJavaはこの部分覆い隠してますが、結局使っているので理解しないとまれにハマって抜け出せなくなる部分と思います。(知っていてもハマりますから、知らないと悲惨かと。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/14 11:54

    横失礼
    循環参照はしばしば問題を引き起こすので、可能な限り子供に親の参照を持たせないようにしますね。
    例えば、親で子供を監視するようにします。また下記ルールを守ります。
    1.特殊な親子関係は汎用コレクションをラップして親子関係専用のコレクションにする
    2.コレクションの操作が複雑な場合、ラップクラスにメソッドとして設ける
    3.ユニットテストを書く(GC含む)
    C#はきっちりとしたことを1つずつやっていくこと前提の言語という印象です。

    キャンセル

  • 2017/02/14 13:13

    やっと理解できた気がします。

    C/C++は不正メモリにアクセスした時、規格上は未定義ですが落としてくれる場合が多いです。参照を消し忘れると落ちるわけです。運良くバグを見つけやすいということかも知れません。(これに頼るといつかひどい目に会いますが。)
    それに対してC#は参照を消し忘れても絶対に落ちませんね。

    参照の消し忘れは本来あってはならないことです。でもバグはいつでも忍び込みます。C/C++は運がよければ落ちてくれるけど、C#は絶対落ちないので参照消し忘れバグの検出に苦しんでいるということですね。
    なるほど。確かに頭の痛い問題です。

    参照を全て消すという消極的な削除ではなく、インスタンスを明示的に削除とマークして、そこへアクセスしたら落ちるような機能があればよいですね。
    言語仕様上C#はそのような機能をサポートしていなので、プログラマ側で作るしかないです。ノード・クラスにそのような仕掛けを仕込むのがベストかも知れません。

    キャンセル

  • 2017/02/16 02:27 編集

    haru666さん

    > 循環参照はしばしば問題を引き起こすので、可能な限り子供に親の参照を持たせないようにしますね。
    例えば、親で子供を監視するようにします。また下記ルールを守ります。
    1.特殊な親子関係は汎用コレクションをラップして親子関係専用のコレクションにする
    2.コレクションの操作が複雑な場合、ラップクラスにメソッドとして設ける
    3.ユニットテストを書く(GC含む)

    循環参照って怖いですね。やらないほうがいいのは知っていましたが今回は身に沁みました。ただし親を参照する必要はあるのでテストで確認するのが現実的ですね。(今回も最小構成ケースでテスト書きました)

    > C#はきっちりとしたことを1つずつやっていくこと前提の言語という印象です。

    こちら凄くよくわかります。そもそも仕様上ハマるポイントがいくつもあるのはそういう実装は推奨されないということなのでしょうね。(やろうと思えばunsafeコードでポインタ使えますが・・・。)

    Chironianさんがおっしゃっていることもとても参考になりました。確かに落ちる仕組みがあれば参照バグに気づけますね。

    ただし、自分で作らなければいけないレベルになってしまうということは前おっしゃっていたようにオブジェクト指向的に(もしくはC#での実装)との相性が悪いのかもしれませんね。

    慣れると凄く書きやすい反面、コードやメモリ参照の仕組みを理解していないと罠にはまりやすい言語だと思います。最近まではもう長いことC#触ってるので、テクニカルなコードは書けなくてもやってはいけないコードを書かない自負はあったのですが今回の件はいい薬になりました。

    ご意見ありがとうございました。

    キャンセル

checkベストアンサー

+2

Visual Studioのデバッグで物足りないのであれば、windbgでsos拡張を使用するのがおすすめです。
Debugging Managed Code Using the Windows Debugger
windbg sos で検索すれば解説サイトがいくつか出てきます。

特に参照消し忘れのようなバグに悩まされているため, メモリの動きがどのようになっているか見る方法や, 参照している変数の調べ方などデバッグに重点を置いた内容の情報を探しています。

!DumpHeapや!gcrootで調べることができます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/14 10:47

    この情報素晴らしいですね。
    まさに欲しかった情報でした。
    なのでベストアンサーとさせていただきます。

    キャンセル

+1

Roslyn の日本語で読める解説が多い、岩永さんのhttp://ufcpp.net/blog/ は見ていますね。
超有名ですけど。

参照の消し忘れというと弱参照でしょうか?
http://ufcpp.net/study/csharp/RmWeakReference.html

あと、今時は、ソースコードがオープンなので、それを読むのもいいと思います。
http://qiita.com/kiichi54321/items/1699f3182ad3665dc7de

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/13 15:48 編集

    ありがとうございます。読みます!
    やはり弱参照の仕組みを作るのが確実ですかね。
    pythonだと当たり前に使いますがC#だとメモリの解放はGCに任せる方がパフォーマンス的にはいいというので,ちょっと消極的な選択肢でしたが,検討しますね。

    キャンセル

  • 2017/02/13 17:09

    弱参照自体は、どうしてもこういう実装しないとダメ、というものでしかやらないほうがいいですね。
    設計で回避できるものがほとんどだと思います。

    そういえば、デバッグ環境としては、テストプロジェクトは便利ですよ。 http://qiita.com/kiichi54321/items/33238ec7e8a5c95b5026 

    キャンセル

  • 2017/02/13 19:47

    ありがとうございます。テストプロジェクト使ってます。
    知らないと消耗するだろうなぁと思って使ってますね。

    キャンセル

+1

僕はそんなに色々な本を読んでる方じゃないですし、僕が実際に読んだのは第3版なので確実とは言えませんが
プログラミング.NET Framework 第4版は良い本かなと。

少し値段が高いし、もうC# 7.0が囁かれる中でC#5時代の本っていうのがなんかアレですが。
HOW TO本ではないので、デバッグ手法やIDE拡張なんかは入ってないです。
また、.NET Framework…というかCLRの話なので直接的なILの話はほとんど入っていません。
組んだコードがどのように実行されるのか、ということの解説本です。
.NETの文字列の仕組みだったり、ロック、ガベージコレクタの細かい動作を僕に教えてくれたのはこの本です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/13 15:47

    ありがとうございます!読んでみます!

    キャンセル

+1

定番&無料なものとしては本家のドキュメントをですかね。

(msdn)共通言語ランタイム (CLR)

(msdn).NET Framework 4.6 および 4.5

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/13 15:47

    ありがとうございます!特に知りたい項目が詳しく書かれてそうなので読みます。

    キャンセル

  • 2017/02/13 15:52

    日本語のものでも物によっては機械翻訳(直訳)があるので原文を読めるなら原文を見るといいですよ。

    キャンセル

  • 2017/02/13 15:58

    ありがとうございます。私も明らか日本語役がおかしい著書に対しては基本的に原文読んでいます。

    キャンセル

+1

もう、古い本になって入手しづらいかもしれませんが、  
The Root of .NET Framework  
は読んでおくべきかと思います。  
.NET の中や、デバッグ手法等が日本語で書かれている貴重な本です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/13 15:49

    ありがとうございます。探して読みます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる