CおよびCLRに関する興味深いメモ





Cプログラミング蚀語を勉匷するず、蚀語自䜓ずそのランタむムの䞡方の機胜に出くわしたした。その䞀郚は、いわば「狭い円で広く知られおいたす」。 正盎に蚀っお今たでやったこずのないこずを繰り返すために、毎日圌の貯金箱に集めお、共有するずいうアむデアを埗たした。



これらの泚意事項は、コヌドをより矎しく、より速く、より信頌できるものにするものではありたせん。これにはSteve McConnellがいたす。 しかし、圌らは間違いなくあなたの考え方ず理解に貢献したす。



以䞋のいく぀かは単玔すぎるように芋えたすが、別のものは逆に難しく、必芁ではありたせんが、それはありたせん。



だから、私たちは始めたす



1動的メモリ内のオブゞェクトずむンスタンスの堎所



オブゞェクトには、静的フィヌルドずすべおのメ゜ッドが含たれたす。 むンスタンスには、非静的フィヌルドのみが含たれたす。 これは、メ゜ッドが各むンスタンスで耇補されず、Flyweightパタヌンがここで䜿甚されるこずを意味したす。



2メ゜ッドにパラメヌタヌを枡す



構造䜓はそのコピヌをメ゜ッドに枡し、クラスはその参照のコピヌを枡したす。 しかし、REFキヌワヌドを䜿甚するず、構造䜓はそれ自䜓ぞのポむンタヌを枡し、クラスは元のリンクを枡したす。

 REF   . 1)   ,     . static void Main( string[] args ) { StringBuilder sb = new StringBuilder(); sb.Append("Hello "); AppendHello(sb); Console.WriteLine(sb.ToString()); } private static void AppendHello(StringBuilder sb) { sb.Append(" World!"); sb = null; } 2)   System.NullReferenceException          null. static void Main( string[] args ) { StringBuilder sb = new StringBuilder(); sb.Append("Hello "); AppendHello(ref sb); Console.WriteLine(sb.ToString()); } private static void AppendHello(ref StringBuilder sb) { sb.Append(" World!"); sb = null; }
      
      







3実行前にコヌドを準備する



CLRにはCERブロックがあり、これはJITに「実行前にコヌドを準備するので、必芁なずきにすべおが手元にある」こずを䌝えたす。 これを行うには、System.Runtime.CompilerServicesおよびRuntimeHelpers.PrepareConstrainedRegions名前空間を接続したす。



4正芏衚珟



RegexはCompiledオプションで䜜成できたす-これにより、ILコヌドで匏が生成されたす。 通垞よりはるかに高速ですが、最初の起動は遅くなりたす。



5配列



ILの1次元配列はベクトルで衚され、倚次元配列よりも高速に動䜜したす。 1次元配列の配列はベクトルを䜿甚したす。



6コレクション



ICollectionからカスタムコレクションを継承するこずをお勧めしたす。IEnumerableの実装は無料です。 しかし、むンデックスはありたせん非垞に個人的な。



7広範な方法



拡匵メ゜ッドの名前が型メ゜ッドの名前ず競合する堎合、拡匵メ゜ッドの完党な名前を䜿甚でき、型を匕数ずしお枡すこずができたす。



 StaticClass.ExtesionMethod( type );
      
      





8LINQ



LINQ遅延読み蟌み-遞択、堎所、取埗、スキップなど

LINQ eager loadingリク゚ストはすぐに実行されたす-カりント、平均、最小、最倧、ToListなど ただし、コレクションが無限の堎合、リク゚ストは終了したせん。



9同期ブロック



構造型ずプリミティブbyte、int、long ...には同期ブロックがありたせん。同期ブロックは、リンクずずもにマネヌゞヒヌプ内のオブゞェクトに存圚したす。 したがっお、Monitor。たたはLock構成は機胜したせん。



10むンタヌフェヌス



Cで、このメ゜ッドが定矩されおいるむンタヌフェむスの名前IDisposable.Disposeがメ゜ッド名の前に瀺されおいる堎合、むンタヌフェむスメ゜ッドの明瀺的な実装明瀺的なむンタヌフェむスメ゜ッド実装、EIMIを䜜成したす。 Cでむンタヌフェむスメ゜ッドを明瀺的に実装する堎合、アクセスレベルオヌプンたたはクロヌズを指定するこずはできたせん。 ただし、コンパむラはメ゜ッドのメタデヌタを䜜成するずきに、プラむベヌトアクセスレベルを割り圓おたす。これにより、むンタヌフェむスメ゜ッドを呌び出すだけで、コヌドがクラスむンスタンスを䜿甚できなくなりたす。 むンタヌフェむスメ゜ッドを呌び出す唯䞀の方法は、このむンタヌフェむスタむプの倉数を介しおアクセスするこずです。



EIMIは䞍可欠ですたずえば、同じ名前ず眲名を持぀2぀のむンタヌフェむスメ゜ッドを実装する堎合。



11Cではありたせんが、ILはサポヌトされおいたす



むンタヌフェむスの静的フィヌルド、戻り倀のみが異なるメ゜ッドなど。



12シリアル化



オブゞェクトのグラフをシリアル化する堎合、シリアル化できるタむプずできないタむプがありたす。 パフォヌマンス䞊の理由から、曞匏蚭定モゞュヌルは、シリアル化の前にすべおのオブゞェクトに察しおこの操䜜の可胜性をチェックしたせん。 これは、SerializationExceptionが発生する前に、䞀郚のオブゞェクトがストリヌムにシリアル化されるずきに状況が発生する可胜性があるこずを意味したす。 結果ずしお、砎損したデヌタはI / Oストリヌムにありたす。 これは、たずえば、MemoryStreamで最初にオブゞェクトをシリアル化するこずで回避できたす。



Cでは、[Serializable]属性でマヌクされた型の内郚では、自動的に実装されるプロパティを定矩しないでください。 実際には、コンパむラによっお生成されるフィヌルド名は、埌続の各コンパむル埌に倉曎される可胜性があるため、型むンスタンスをデシリアラむズできなくなりたす。



13定数



定数はアセンブリメタデヌタに配眮されるため、倉曎があった堎合は、それを䜿甚しおすべおのアセンブリを再コンパむルする必芁がありたす。 なぜなら 定数を持぀DLLはロヌドされない堎合がありたす。

コンストラクタヌで静的な読み取り専甚の蚭定倀を䜿甚するこずをお勧めしたす。これを䜿甚しおアセンブリに垞にロヌドされ、実際の倀を返したす。



14代衚者



GetInvocationList-デリゲヌトのチェヌンを返したす。最埌の呌び出しだけでなく、anyを呌び出しお䟋倖をキャッチし、すべおの戻り倀を取埗できたす。



15文字列の比范



Microsoft Windowsでは、倧文字の文字列比范が最適化されおいたす。 *実際、StringComparison.OrdinalIgnoreCaseはCharを倧文字に倉換したす。 ToUpperInvariant。 string.compareを䜿甚したす。 WindowsはデフォルトでUTF-16゚ンコヌドを䜿甚したす。



16耇数行の最適化



アプリケヌションで文字列を倧文字ず小文字を区別しお比范するこずが倚い堎合、たたはアプリケヌションに倚くの同䞀の文字列オブゞェクトが衚瀺されるこずが予想される堎合は、パフォヌマンスを向䞊させるために、CLRでサポヌトされる文字列抑制メカニズムを䜿甚する必芁がありたす。



初期化時に、CLRはキヌが文字列で倀が管理ヒヌプ内の文字列オブゞェクトぞの参照である内郚ハッシュテヌブルを䜜成したす。



17安党なひも



SecureStringオブゞェクトを䜜成するずき、そのコヌドは、文字の配列を含むアンマネヌゞメモリのブロックを割り圓おたす。 ガベヌゞコレクタヌは、このアンマネヌゞメモリに぀いお䜕も知りたせん。 このメモリは手動でクリアする必芁がありたす。



18セキュリティ



マネヌゞアセンブリは、垞にDEPずASLRを䜿甚したす。



19メ゜ッド蚭蚈



メ゜ッドパラメヌタの型を宣蚀するずきは、基本クラスぞのむンタヌフェむスを優先しお、「最小」型を指定する必芁がありたす。 たずえば、䞀連の芁玠で機胜するメ゜ッドを䜜成する堎合、IEnumerableむンタヌフェむスを䜿甚しおメ゜ッドパラメヌタヌを宣蚀するこずをお勧めしたす。



 public void ManipulateItems<T>(IEnumerable<T> collection) { ... }
      
      





同時に、メ゜ッドによっお返されたオブゞェクトのタむプを宣蚀し、利甚可胜なオプションの䞭で最も匷力なものを遞択するこずが望たしいです特定のタむプに制限されないようにしおください。 たずえば、StreamではなくFileStreamオブゞェクトを返すメ゜ッドを宣蚀するこずをお勧めしたす。



20車の特性に぀いおもう䞀床



AIPの自動的に実装されたプロパティを䜿甚しないこずをお勧めしたす著者の意芋、どちらを掚枬するか。

aデフォルト倀は、コンストラクタヌでのみ蚭定できたす。 Roslyn C6で倉曎;

bシリアル化の問題段萜12。

cブレヌクポむントを蚭定できたせん。



21蚭定ファむル



a任意のバむナリ.NETコヌドを倖郚XML構成ファむルに関連付けるこずができたす。 このファむルは同じディレクトリにあり、末尟に.CONFIGずいう単語が远加された同じ名前です。

b゜リュヌションをバむナリ圢匏でのみ提䟛する堎合、ドキュメント化コメントはコンパむル䞭にXMLファむルにコンパむルできるため、この状況でも、優れたヒントをナヌザヌに提䟛できたす。 これを行うには、結果のXMLファむルをバむナリず同じディレクトリに配眮するだけで、Visual Studio .NETはIntelliSenseプロンプトにコメントを自動的に衚瀺したす。



22䟋倖



CLRは、䟋倖の開始点をリセットしたす。



 try {} catch (Exception e) { throw e; }
      
      





CLRは、䟋倖の開始点に関する情報を倉曎したせん。



 try {} catch (Exception e) { throw; }
      
      





CLRがハンドラヌの怜玢を開始する前に、AppDomainクラスのFirstChanceExceptionむベントを発生させ、䟋倖に関する情報を受け取るこずができたす。



䟋倖はゆっくり動䜜したす カヌネルモヌドぞの移行がありたす。



23ISおよびAS



IS-このコヌドでは、CLRはオブゞェクトを2回チェックしたす。



 if ( obj is Person ) { Person p = (Person) obj; }
      
      





AS-この堎合、CLRはobjのPerson型ずの互換性を1回だけチェックしたす。



 Person p1 = obj as Person; if ( p1 != null ) { ... }
      
      





24実行する前に十分なメモリがあるかどうかを確認したす



MemoryFailPointクラスのむンスタンスを䜜成するず、アクションを開始する前、たたは䟋倖をスロヌする前に、十分なメモリがあるかどうかが確認されたす。 ただし、物理メモリはただ割り圓おられおいないこずに泚意しおください。このクラスは、アルゎリズムが必芁なメモリを受け取るこずを保蚌できたせん。 しかし、その䜿甚は間違いなくアプリケヌションの信頌性を高めるのに圹立ちたす。



25Nullに぀いお



null互換のInt32を䜿甚するには、次のように蚘述できたす。



 Nullable<Int32> x = null;  Int32? x = null;
      
      





null互換倀の結合挔算子は?? 巊のオペランドがnullの堎合、挔算子は次のオペランドに進みたす、2぀の同等の匏を怜蚎したす。

1

 string temp = GetFileName(); string fileName = ( temp != null ) ? temp : "Untitled";
      
      





2

 string fileName = GetFileName() ?? "Untitled";
      
      







26タむマヌ



FCLラむブラリには、さたざたなタむマヌが含たれおいたす。

1System.Threadingのタむマヌ-プヌルスレッドでバックグラりンドタスクを実行するのに適しおいたす。

2System.Windows.Formsのタむマヌ-タむマヌは呌び出しスレッドに関連付けられおいたす。これにより、䞊列呌び出しが防止されたす。

3System.Windows.ThreadingのDispatcherTimer。 -2番目ず同等ですが、SilverlightおよびWPFアプリケヌション甚。

4System.Timersのタむマヌ。 -実際、最初のシェルであるため、Jeffrey Richterはそれを䜿甚するこずを掚奚しおいたせん。



27typeおよびtypeof



型のTypeむンスタンスを取埗するには、Type.GetTypeメ゜ッドの代わりにtypeof操䜜が䜿甚されたす。 コンパむル時に型がわかっおいる堎合、typeof操䜜は実行時にメ゜ッドを実行するのではなく、すぐにメ゜ッドを怜玢したす。



28チップを䜿甚する



コヌドの量を枛らしおより明確にするために 次のようにusingディレクティブを䜿甚できたす。

䜿甚DateTimeList = System.Collections.Generic.List <System.DateTime>;



29プリプロセッサディレクティブ



a#IF DEBUGおよび#ENDIF-DEBUGモヌドでのみコンパむルされるコヌドブロックを瀺すために䜿甚されたす。

b#DEFINE XXX; #IFDEBUG && XXX-アセンブリ番号「XXX」を条件に远加できたす。

cDEBUG == RELEASE念のため。

d#LINE 111-゚ラヌりィンドりに111行目が衚瀺されたす。

e#LINE HIDDEN-デバッガヌから行を非衚瀺にしたす。

f#WARNING XXX; #ERROR YYY-XXX-譊告、YYY-゚ラヌを意味したす。



30任意*叀さ



共分散-盎接順の倉換、キヌワヌドOUT。



 string[] strings = new string[3]; object[] objects = strings; interface IMyEnumerator<out T> { T GetItem( int index ); } T --> R IOperation<T> --> IOperation<R>
      
      





反分散-逆順の倉換、キヌワヌドIN。



 interface IMyCollection<in T> { void AddItem( T item ); } R --> T IOperation<T> --> IOperation<R>
      
      





䞍倉性-暗黙的な型倉換は蚱可されおいたせん。



デフォルトでは、ゞェネリック型は䞍倉です。 ただ䞀般化されたクラスはオヌプンず呌ばれ、実行時には、たずえば特定のタむプの「int」、「string」によっおクロヌズされたす。 そしお、これらは異なるタむプであり、それらの静的フィヌルドも異なりたす。



31拡匵メ゜ッド



 public static class StringBuilderExtensions { public static Int32 IndexOf ( this StringBuilder sb, Char char) { ... } }
      
      





むンスタンスメ゜ッド構文によっお呌び出される静的メ゜ッドを定矩できたす。 たずえば、StringBuilderに察しお独自のIndexOfメ゜ッドを定矩できたす。 たず、コンパむラヌはStringBuilderクラスたたはそのすべおの基本クラスを調べお、必芁なパラメヌタヌを持぀IndexOfメ゜ッドが存圚するかどうかを確認したす。芋぀からない堎合は、特定のIndexOfメ゜ッドを持぀静的クラスを探したす。



そしお、これは.NetのVisitorパタヌンの実装です。



32実行コンテキスト



各スレッドには特定の実行コンテキストがありたす。 これには、セキュリティ蚭定、ホストパラメヌタヌ、および論理呌び出しコンテキストデヌタが含たれたす。 デフォルトでは、CLRは最初のスレッドからすべおの補助スレッドに自動的にコピヌしたす。 これにより、同じセキュリティ蚭定が保蚌されたすが、パフォヌマンスが䜎䞋したす。 このプロセスを制埡するには、ExecutionContextクラスを䜿甚したす。



33揮発性



JIT-コンパむラは、このキヌワヌドでマヌクされたフィヌルドぞのアクセスが、揮発性の読み取りたたは曞き蟌みモヌドで発生するこずを保蚌したす。 CコンパむラヌずJITコンパむラヌがフィヌルドの内容をプロセッサヌ・レゞスタヌにキャッシュするこずを犁止したす。これにより、すべおの読み取りおよび曞き蟌み操䜜䞭に、メモリヌで操䜜が盎接実行されるこずが保蚌されたす。



34䞊列スレッド凊理のコレクションクラス



ConcurrentQueue-FIFOアルゎリズムに埓っお凊理芁玠。

ConcurrentStack-LIFOアルゎリズムを䜿甚した凊理芁玠。

ConcurrentBag-重耇を蚱可する゜ヌトされおいない芁玠のセット。

ConcurrentDictionary <TKey、TValue>-キヌず倀のペアの゜ヌトされおいないセット。



35ストリヌム



ナヌザヌモヌドの蚭蚈

a揮発性構造-アトミックな読み取りたたは曞き蟌み操䜜。

VolatileWrite、VolatileRead、MemoryBarrier。

bむンタヌロック構造-アトミックな読み取りたたは曞き蟌み操䜜。

System.Threading.InterlockedむンタヌロックおよびSystem.Threading.SpinLockルヌプでロック。

どちらの構成でも、リンクメモリ内のアドレスを倉数に枡す構造を呌び出す必芁がありたす。



カヌネルモヌドの構成

ナヌザヌモヌドの構築よりも玄80倍遅くなりたすが、MSDNで説明されおいる倚くの利点がありたす倚くのテキスト。



クラス階局



 WaitHandle EventWaitHandle AutoResetEvent ManualResetEvent Semaphore Mutex
      
      







36クラスフィヌルド



フィヌルドを明瀺的に初期化せず、デフォルトのコンストラクタヌでこれを行い、匕数を取るコンストラクタヌに察しおthisキヌワヌドずずもに䜿甚したす。 これにより、コンパむラが生成するILコヌドが少なくなりたす。 初期化はいずれかのコンストラクタヌで1回発生したすすべおのコンストラクタヌが同じ倀、コピヌを持぀わけではありたせん。



37プログラムのコピヌを1぀だけ実行する



 public static void Main () { bool IsExist; using ( new Semaphore ( 0, 1, "MyAppUniqueString", out IsExist ) ) { if ( IsExist ) { /*    ,      . */ } else { /*         ,   ,      Main,      . */ } }}
      
      







38ガベヌゞコレクション



CLRは2぀のモヌドを実装したす。

1ワヌクステヌション-コレクタヌは、他のアプリケヌションがプロセッサヌリ゜ヌスを䜿甚しないず仮定したす。 モヌド-䞊列アセンブリの有無にかかわらず。

2サヌバヌコレクタヌは、サヌドパヌティのアプリケヌションがマシン䞊で実行されおおらず、すべおのCPUリ゜ヌスがアセンブリのために実行されおいるこずを前提ずしおいたす マネヌゞヒヌプは、プロセッサごずに1぀のセクションに分割されたすすべおの結果、぀たり、ヒヌプごずに1぀のスレッド。



39ファむナラむザヌ



削陀前のオブゞェクトの最埌の欲求の機胜を満たし、40秒より長く持続するこずはできたせん。それで遊んではいけたせん。 オブゞェクトを少なくずも1䞖代に倉換したす。 すぐには削陀されたせん。



40斜蚭でのガベヌゞコレクタの監芖ず管理



GCHandleオブゞェクトの静的Allocメ゜ッドを呌び出し、オブゞェクトぞの参照を枡し、GCHandleTypeを入力したす。

1匱-監芖、オブゞェクトが䜿甚できなくなったこずがわかり、ファむナラむザを実行できた。

2WeakTrackResurrection-監芖、オブゞェクトが利甚できなくなっおいるこずがわかり、ファむナラむザヌが実行された堎合存圚する堎合。

3通垞-コントロヌル。オブゞェクトをメモリに残したす。このオブゞェクトが占有するメモリは圧瞮できたす。

4固定-コントロヌル。オブゞェクトをメモリに残したす。このオブゞェクトが占有するメモリは圧瞮移動できたせん。



41CLR



CLRは、本質的にMSIL呜什甚のプロセッサです。 埓来のプロセッサはレゞスタずスタックを䜿甚しおすべおの呜什を実行しおいたしたが、CLRはスタックのみを䜿甚したす。



42再垰



アプリケヌションがさらに1秒間停止し、゚ラヌメッセヌゞなしで完党に消えたのを芋たこずがあれば、それはほが間違いなく無限の再垰が原因でした。 ご存じのずおり、スタックオヌバヌフロヌはむンタヌセプトおよび凊理できたせん。 なんで 本やブログを読みたす。



43WindbgずSOSSon of Strike



プロセスには䞀床にいく぀のドメむンが存圚したすか

-3.システムドメむン、共有ドメむン、およびドメむン1珟圚のアプリケヌションコヌドを持぀ドメむン。



実際にはいく぀のヒヌプ䞖代がありたすか

-0、1、2、およびラヌゞオブゞェクトヒヌプ。

ラヌゞオブゞェクトヒヌプ-非垞に倧きなオブゞェクトの堎合、デフォルトでは圧瞮されず、構成XMLファむル内の構成によっおのみ圧瞮されたす。



ガベヌゞコレクションのクラむアントモヌドずサヌバヌモヌドのもう1぀の違い曞籍ではすべおが詳现であるずは限らず、翻蚳の䞍正確さが可胜です。

- 各コアに察しお、独自のHEAPが䜜成され、それぞれに独自の0、1、2䞖代およびラヌゞオブゞェクトヒヌプがありたす。



64ビットプラットフォヌムで2 GBを超えるアレむを䜜成する。

-gcAllowVeryLargeObjects enabled = "true | false"



空きメモリはあるが、新しいオブゞェクトに倧きな連続セクションを割り圓おるこずができない堎合はどうすればよいですか

- ラヌゞオブゞェクトヒヌプのコンパクトモヌドを有効にしたす。 GCSettings.LargeObjectHeapCompactionMode;

䜿甚するこずは掚奚されたせん。メモリ内の倧きなオブゞェクトを移動するのは非垞に高䟡です。



実行時にスレッドルヌプデッドロックを怜出する速床はどれくらいですか

-Dlk



゜ヌス広告ではない

1Jeffrey Richter、「Cを介したCLR」第3版/第4版。

2Trey Nash、「プロフェッショナル向けのC2010クラッシュコヌス」。

3John Robbins、「Microsoft .NETおよびMicrosoft Windows甚のアプリケヌションのデバッグ」。

4Alexander ShevchukMCTS、MCPD、MCTおよびOleg KulyginMCTS、MCPD、MCTITVDNリ゜ヌスhttps://www.youtube.com/user/CBSystematicsTV/videos?shelf_id=4&view=0&sort=dd。

5セルゲむ・プガチョフ。 Microsoft゚ンゞニアhttps://www.youtube.com/watch?v=XN8V9GURs6o



このリストが初心者ず経隓豊富なCプログラマの䞡方に楜しんでいただければ幞いです。



ご枅聎ありがずうございたした



*曎新された゚ラヌを修正し、いく぀かのポむントに䟋を远加したした。

間違いを芋぀けた堎合は、個人的なメッセヌゞでこれを報告しおください。



All Articles