If you are not sure if the website you would like to visit is secure, you can verify it here. Enter the website address of the page and see parts of its content and the thumbnail images on this site. None (if any) dangerous scripts on the referenced page will be executed. Additionally, if the selected site contains subpages, you can verify it (review) in batches containing 5 pages.
favicon.ico: engineering.grani.jp - Grani, Inc..

site address: engineering.grani.jp redirected to: engineering.grani.jp

site title: Grani, Inc.

Our opinion (on Friday 29 March 2024 14:53:09 GMT):

GREEN status (no comments) - no comments
After content analysis of this website we propose the following hashtags:


Hashtags existing on this website:



Proceed to the page?Powered by: Very Tiny URL Shortener at http://vturl.net VeryTinyURL

Meta tags:

Headings (most frequently used words):

まとめ, mt, addr, dumpheap, dumpmt, 型情報を出力する, visual, for, messagepack, or, string, メモ, methodtable, トラブルシューティング, 怪しそうな型を見つける, オブジェクトの統計情報を出力する, threadによるゲームループのホスト, 型から生きているオブジェクトの一覧を出力する, パフォーマンス, grani, dedicated, サーバーサイドゲームループ, 独自の追加専用ハッシュテーブルを作る, benchmarkdotnet, hashtableの秘密, apiリストを確認する, linqpadでec2インスタンスの情報を取得する, linqpadって, apiの便利さと複雑さ, aws, やデッドロックを解析する, オブジェクトからgcのルートとなるオブジェクトを探す, ファイナライゼーションキューの情報を取得する, ヒープのオブジェクト統計情報を取得する, dead, ファイナライザースレッドがブロック状態かどうかを調べる, eeclass, dumpclass, md, obj, gcroot, オブジェクトの参照元を探す, から死んでいるオブジェクトの一覧を取得する, stat, live, から生きているオブジェクトの一覧を取得する, finalizequeue, スタックオーバーフローを解析する, gc, eeheap, heapstat, ヒープの状況を取得する, cpu100, pa_resourcetracker, ダンプを収集する, appendix, リアルタイム通信におけるc, でのバイナリの読み方と最適化法, に見るc, でtypeをキーにしたdictionaryのパフォーマンス比較と最速コードの実装, apiを5倍理解する, linqpadでaws, studioでの可視化によるc, ダンプ解析入門, internによるunityでの省メモリ化ハック, windbgを試してみる, awaitによるサーバーサイドゲームループ, debugdiagを試してみる, studioを試してみる, どのツールで解析すれば, ダンプのみどころ, 前提, お品書き, netのメモリ状態を探りたい, メモリダンプから, blog, async, 株式会社グラニはc, のimessagepackserializationcallbackreceiver, 雑基礎知識, internについて, を使う, engineering, ものすごいメモリプロファイラ, netアプリケーションコードから知りたい, ファイナライザーの実行を, windbgでもっと簡単に詳しく, windbgコマンドいろいろ, windbgでの解析のやっていきかた, ダンプファイルを開いてまずはsos, を中心として, インストール, ハングやクラッシュを調べる, おまけ, プロセスのダンプをとる, コンピューターで動作している32bit, 64bit, vr開発を行っています, unity, net, asp, 出力の読み方,

Text of the page (most frequently used words):
#system (67), var (57), #public (46), key (40), new (36), #string (35), #thread (35), for (33), #action (32), #void (30), 2017 (29), #00007ffb (29), int (27), #class (26), 00007ffab4265bc0 (26), #consoleapp15 (26), int32 (24), return (23), this (23), objects (23), clr (23), entry (22), size (22), null (22), #addr (22), 0000001e (21), hashtable (21), 0000000000000000 (20), consoleapp18 (20), generation (20), true (20), none (19), 000 (19), buckets (19), object (18), value (17), next (16), name (16), static (16), tkey (16), dumpheap (16), heap (16), count (16), out (15), console (15), type (15), writeline (14), tvalue (14), program (14), allocated (13), visual (13), net (13), all (12), 黒騎士と白の魔王 (12), concurrentdictionary (12), resultingvalue (12), starts (12), finalizable (12), comparer (11), preemptive (11), lock (11), 000001c1c4824720 (11), 00000004 (11), gcroot (11), hash (10), loadfactor (10), threadsafehashtable (10), while (10), dict (10), valuefactory (10), has (10), roots (10), dictionary (10), microsoft (10), neuecc (10), segment (9), threading (9), from (9), add (9), total (9), typeof (9), mean (9), newentryornull (9), trygetvalue (9), iformatprovider (9), main (9), capacity (9), length (9), loh (9), error (8), collections (8), concurrentdict (8), run (8), searchlastentry (8), 00007ffc3e0f5af8 (8), args (8), ukn (8), windows (8), まとめ (8), 21220 (8), benchmark (8), default (8), list (8), ref (8), item (8), messagepack (8), false (7), equals (7), finalization (7), newkey (7), methodtable (7), gameloopthread (7), hogehoge (7), the (7), tags (7), reachable (7), table (7), continuation (7), finalizerthread (7), iconvertible (7), gameloopawaiter (7), method (7), array (6), see (6), bool (6), mscorlib (6), usequeuecount (6), ready (6), usequeue (6), fixed (6), else (6), 00000000 (6), write (6), stddev (6), scaled (6), begin (6), successadd (6), nextframe (6), トラブルシューティング (6), await (6), tostring (6), statistics (6), totalsize (6), intptr (6), generic (5), gethashcode (5), isqueuea (5), scaledsd (5), framemilliseconds (5), stat (5), func (5), 100000 (5), threads (5), volatile (5), free (5), dumpmt (5), float (5), str3 (5), live (5), queuebcount (5), ctoの河合 (5), only (5), equalitycomparer (5), intern (5), str4 (5), 000001c1c6fbccf8 (5), aws (5), set (5), get (5), queueacount (5), cache (4), readonly (4), threadsafetypekeyhashtable (4), benchmarkconfig (4), ntdll (4), 0x14 (4), switcher (4), _values (4), mta (4), parallel (4), assembly (4), context (4), field (4), exe (4), notification (4), 000001e583e12eb0 (4), 000001c652f54ba8 (4), description (4), 000001c6545021c8 (4), 000001c6547c8048 (4), win32 (4), safehandles (4), imessagepackserializationcallbackreceiver (4), eeheap (4), large (4), bytes (4), そして (4), heapstat (4), grpc (4), registercompletion (4), とはいえ (4), オブジェクトの統計情報を出力する (4), studio (4), addtobuckets (4), nextbucket (4), studioでの可視化によるc (4), ダンプ解析入門 (4), accesskeyid (4), secretaccesskey (4), ec2client (4), tryadd (4), shouldcontinue (4), snip (4), queueb (4), kawai (4), sleep (4), response (4), 型情報を出力する (4), isinterned (4), 000001c54a596e18 (4), eeclass (4), queuea (4), unique (4), threadnumber (4), 46542800 (4), handle (4), found (4), つまり (4), str2 (3), dll (3), api (3), hoge (3), yoshifumi (3), enterprise (3), dump (3), state (3), finalize (3), result (3), memory (3), mdt (3), version (3), target (3), str1 (3), foo (3), child (3), http (3), str5 (3), byte (3), namespace (3), しかし (3), are (3), というと (3), pa_resourcetracker (3), str6 (3), 00007ffb11b49428 (3), break (3), allocation (3), ephemeral (3), 000001c6548f44d8 (3), 000001c6545ebf40 (3), 000001c6530294b8 (3), released (3), interfaces (3), finalizequeue (3), ただし (3), safe (3), address (3), dead (3), call (3), use (3), initialsize (3), gate (3), start (3), 262158024 (3), ですが (3), newarray (3), debugdiag (3), 閉じる (3), 64bit (3), bit (3), grani (3), x86 (3), iequalitycomparer (3), calculatecapacity (3), tryaddinternal (3), nextcapacity (3), asp (3), 怪しそうな型を見つける (3), 型から生きているオブジェクトの一覧を出力する (3), 2400000 (3), オブジェクトからgcのルートとなるオブジェクトを探す (3), pinned (3), これが (3), sos (3), ensurecapacity (3), 000001c1c7fd5eb8 (3), finalizer (3), warning (3), dictionarybenchmark (3), file (3), 100 (3), callfinalizer (3), dumpclass (3), projects (3), foreach (3), 00007ffb11b469f8 (3), slots (3), samplerate (3), gameloopthreadrun (3), datadogstats (3), number (3), site (3), mdtoken (3), sri_1128 (2), gettypes (2), baseline (2), setup (2), これは (2), benchmarkswitcher (2), 950 (2), newentry (2), and (2), baselinebenchmark (2), globalsetup (2), tablesize (2), comaprer (2), measurements (2), standard (2), amazonec2client (2), deviation (2), writerlock (2), currentbenchmark (2), config (2), parallelbenchmark (2), gen (2), benchmarkdotnet (2), 2136 (2), 読者になる (2), 75f (2), parallelconcurrentdictionary (2), そのため (2), parallelhashtable (2), read (2), paralleldictionary (2), deserialize (2), 例えば (2), managed (2), single (2), debug (2), initialcapacity (2), collectionsize (2), not_found (2), operations (2), that (2), per (2), etc (2), msdn (2), regionendpoint (2), 00007ffa (2), apnortheast1 (2), 00007ffab4266120 (2), から生きているオブジェクトの一覧を取得する (2), オブジェクトの数 (2), 出力の読み方 (2), 00007ffab4266518 (2), 00007ffab4265fa0 (2), 00007ffab42663a0 (2), から死んでいるオブジェクトの一覧を取得する (2), つまりc (2), のデストラクタ (2), ファイナライゼーションキューの情報を取得する (2), 253804240 (2), heap0 (2), heap1 (2), 1000 (2), 1381 (2), 269498448 (2), module (2), 0x21 (2), exception (2), 1f058 (2), ファイナライザースレッドがブロック状態かどうかを調べる (2), gac_64 (2), 0_4 (2), 0__b77a5c561934e089 (2), 00007ffb114b1000 (2), obj (2), vtable (2), instance (2), methoddesc (2), compareto (2), these (2), not (2), 0000000470fbeba0 (2), オブジェクトの参照元を探す (2), heap2 (2), heap3 (2), basethreadinitthunk (2), studioを試してみる (2), referenced (2), types (2), paths (2), root (2), values (2), valueb (2), に限る (2), windbg (2), analysis (2), どのツールで解析すれば (2), ダンプのみどころ (2), x64 (2), コンピューターで動作している32bit (2), プロセスのダンプをとる (2), お品書き (2), engineering (2), debugdiagを試してみる (2), ハングやクラッシュを調べる (2), heap4 (2), ヒープのオブジェクト統計情報を取得する (2), heap5 (2), heap6 (2), heap7 (2), 8024soh (2), 8248soh (2), ヒープの状況を取得する (2), ヒープの使用状況 (2), windbgコマンドいろいろ (2), おまけ (2), windbgでの解析のやっていきかた (2), 要するに型 (2), 雑基礎知識 (2), ダンプファイルを開いてまずはsos (2), インストール (2), windbgを試してみる (2), crashhanganalysis (2), hogehoge2 (2), rtluserthreadstart (2), kernel32 (2), describeinstances (2), この場合 (2), referenceequals (2), encoding (2), utf8 (2), empty (2), 通常攻撃 (2), mayuki (2), registerforfullgcnotification (2), _thread (2), waitforfullgcapproach (2), gcnotificationstatus (2), インターン化した文字列はずっとメモリ領域を確保し続け (2), waitforfullgccomplete (2), dmp (2), huga (2), linqpad (2), を使います (2), こんにちは (2), iis (2), runtime (2), homecontroller (2), 混合でデバッグ (2), getasync (2), str (2), com (2), と思いきや (2), reporting (2), mode (2), dumps (2), succeeded (2), ファイナライザーの実行を (2), 2227ef91 (2), 0x6c (2), 13966751 (2), finalizerthreadworker (2), 139666cc (2), managedthreadbase_dispatchinner (2), 0x39 (2), 1396660a (2), managedthreadbase_dispatchmiddle (2), 13a628ba (2), b434142e (2), managedthreadbase_dispatchouter (2), 0x75 (2), 13b2222f (2), finalizerthreadstart (2), 0x10a (2), 1f711fe4 (2), intermediatethreadproc (2), 0x86 (2), netアプリケーションコードから知りたい (2), clrstack (2), 000001e583e12e70 (2), キュー (2), を表示 (2), ファイナライゼーションキュー (2), sosex (2), windbgでもっと簡単に詳しく (2), appendix (2), 0000001ea677f1d8 (2), unable (2), verify (2), checksum (2), 0000001ea677f728 (2), finalizeallobjects (2), 13k (2), retaddr (2), kernelbase (2), getoradd (2), blog (2), async (2), internal (2), objectself (2), core (2), unity (2), でtypeをキーにしたdictionaryのパフォーマンス比較と最速コードの実装 (2), クライアント開発と現実的なunirx使いこなし術 (2), writer (2), vr開発を行っています (2), こうなる (2), そもそも (2), ベンチマークに追加 (2), 結果はこうです (2), で統一したサーバー (2), にみるc (2), internによるunityでの省メモリ化ハック (2), tokyo講演 (2), newlength (2), unite (2), linqpadでaws (2), apiを5倍理解する (2), メモリダンプから (2), による (2), self (2), netのメモリ状態を探りたい (2), frameaction (2), という流れになっています (2), 株式会社グラニはc (2), gauge (2), invoke (2), 最後に (2), を中心として (2), runinthread (2), というわけで (2), 2010 (2), の一覧が出力されます, case, アプリケーションのダンプから名寄せできたりなど, オプションを付けて呼び出すとメソッド, methoddescriptor, 実際に, デバッグ性もむしろ向上します, threadの単純さのほうを取りました, threadpriority, priority, queue, yet, threadに名前をつけることにより, parameterizedthreadstart, apiは, where, threadpoolが使われるのは向いていません, キューにたまったactionを実行し, sleepして次のループを待つ, 専用スレッドを使う理由は, 超長期, サーバーのライフサイクルと等しい, に実行されるものであることが一つです, 指定したオブジェクトの参照元を出力します, に対して実行すると以下のような結果が得られます, 例えば先ほどの生きているオブジェクトのアドレスの, 000001c2c6db1ff0, は除算による算出で, 00007ffab437098e, このような場合, があることがわかります, オブジェクト, のルートには, この結果からオブジェクト, に対して実行するとルートとなるものがないことがわかります, methodtableのアドレスを指定して情報を出力します, taskにもlongrunningオプションがあり, 場合によってはこれからファイナライザーが実行するぞいっとなっているとfinalizerqueueから参照されていることがあります, 専用スレッド上で動かすこと自体は可能であるが, taskの機能性が不要であること, positives, ただたんにループ回してsleepするだけ, may, themselves, register, 一方ですでに参照のなくなったオブジェクトのアドレス, 00007ffb115989e0, normal, 0x0, prejit, 00007ffb114b7580, 00007ffb1195ce50, 00007ffb11598898, 00007ffb118ed028, 00007ffb11598868, 00007ffb118ed000, 00007ffb115988b0, 00007ffb118ed018, jit, ifacemap, ifaces, stopwatch, componentsize, 00007ffb11598838, 0x18, basesize, 00000000020000fb, 00007ffb11561b80, startnew, restart, stop, eeclassのアドレスを指定して情報を出力します, shared, 4000274, m_firstchar, char, 4000270, 00007ffb118ecff8, copy, toint32, tochar, 00007ffb11598a10, 00007ffb118ed030, touint16, 00007ffb115989f8, 00007ffb11922820, toint16, 000001c1c8031110, 00007ffb11922868, tobyte, 00007ffb115989c8, 00007ffb11922818, tosbyte, 00007ffb115989b0, 00007ffb11922810, 00007ffb11598998, 00007ffb118ecff0, 00007ffb115988f0, 00007ffb11598850, 00007ffb11922858, 00007ffb11598880, 00007ffb11922838, 00007ffb115988d8, 00007ffb118ed010, 00007ffb118ed020, 00007ffb11922848, 00007ffb11598968, gettypecode, 00007ffb11922878, 00007ffb11598980, isbackground, toboolean, 000001c1c80037f0, キュー代わりの配列のせいで, 000001c1c805ea30, 00007ffb11b81960, 00007ffb11b47e50, safefilehandle, 00007ffb11b4a318, readerwriterlock, ならば4000接続まで, 00007ffb11b4d5a8, safepefilehandle, 00007ffb11b4c308, safeviewoffilehandle, 00007ffb11b818d0, safefilemappinghandle, という計算になります, ゲーム性的に, 常にキューが溜まって全フィールドがピーク時の演算が走るわけではないので, 2000, 1ループでの処理時間は均されるのと, 000001c6546dc040, 120833, たとえ1フレーム2フレーム遅延しても, その後のフレームで処理が間に合えばゲームとしてはユーザーに遅延を感じさせないため, 153746, 000001c654402040, 131121, 実際はもう少し余裕があります, 実はリリース当初はこの構成になっていませんでした, 119727, 000001c652e90040, 100717, なっていなかった結果, 192, 192000, 108834, 例えば16コアのサーバーで動かすなら16スレッドを並走させるので, 0x000001c1c7fe6d38, 0x000001c1c8c474b0, 完全にcpuバウンドで, 1スレッドにどれだけの数のbattlefieldをホストできるかで決まります, 000001c1c4854600, heaps, 1フレーム100msで動かすとして, 仮に1フィールドの演算処理が1msかかるなら100フィールドまでなら安全, キューの中身を確認できます, ファイナライゼーションキューとf, それらのキューの状態を各ヒープ領域ごとに取得できます, キューはfinalizerの呼び出しを待っているオブジェクトのキューです, を持っているオブジェクトのキュー, それを, ファイナライゼーションキューはfinalizer, 実際の値は違います, queueに移動してファイナライザーによって処理されます, 参照がなくなるとファイナライゼーションキューからf, でデストラクタを実装しているクラスのオブジェクトのことで, なおfinalize可能なオブジェクトというのはc, 2223078, 1600フィールドということになります, 352169664, 2000964, 1フィールド辺り4人まで格納可能で平均2, 19209216, 200096, 1920864, 20009, かなり不安定でして, それがこのdedicated, 000001c1c808c350, 構造体経由で, gcに回収されない, methodtableのアドレスを元に現在どこからか参照があるであろう, のオブジェクト一覧を出力しています, 以下の例ではmt, 96000, により, 000001c548294520, 000001c548266c00, 000001c5482392e0, 000001c54820b9c0, 000001c1c7073178, 000001c1c7045858, 000001c1c7017f38, 000001c1c6fea618, この結果から1000オブジェクトが生きていることがわかります, ならではのハックとして, キューに再登録しています, m_stringlength, オブジェクトのアドレスの一覧を表示します, gcで回収される, 次回のfull, methodtableのアドレスを元に現在参照されていない, 132576, ややコードがゴチャゴチャしてしまっていますが, 基本的には, 専用スレッドを作り, 000001c54a5694f8, 000001c54a53bbd8, 000001c54a50e2b8, 000001c54a4e0998, アドレスの一覧を表示します, finalizeメソッドを持つすべてのオブジェクトの種類と数とサイズです, sta, awaitを呼ぶと一回のinvokeは終了する, threadによるゲームループに変更後はようやく安定しました, パフォーマンス, threaded, cleaned, syncblocks, 最後に統計が出力されます, 各ヒープ領域ごとに情報が出力され, この値が異常に多い場合にはファイナライザースレッドが何らかの理由でブロックして止まっている可能性があります, ファイナライザーでのブロックを探すには, ファイナライザーによる実行を待っているオブジェクトの数, 経由でキューにこのactionを再登録する, 参照されていないという意味ではないことに注意が必要です, ここにある, キューにまわされます, including, このオブジェクトが必要なくなった時点でf, 000001c653df2c18, 000001c653df0ab0, runにより定期的に呼ばれる, x64なら, x86は, で見れます, ポインタの一覧は, ヒープの範囲ではない, はオブジェクトのポインタが含まれている領域のアドレスです, コード自体は単純なものですが, デストラクタを持つ, nにあるfinalizeメソッドを持つ, 各ヒープのジェネレーション, 00007ffb11b47bb0, iscompleted, elapsed, 139dfde1, 139dfb55, a677f400, gameloopthreadpool, 0xb5, getthread, 139dfc9a, a677f3b0, 0x55, fastcallfinalize, 139dfd69, a677f360, 0x6, fastcallfinalizeworker, a677f330, 0x00007ffa, 13965976, a677f300, 0x4bd32a, mscorlib_ni, frameactionの中でaiの行動選択処理や溜まったコマンドをもとにダメージ与えたり回復させたりのコードが動く, スライド中でもコードを出しましたが, a677f2d0, 黒騎士と白の魔王は以下のようなコードでサーバーサイドでのゲームループを回しています, 0xad, threadnative, 1196d32a, a677f170, 0xa5, 0x5e, a677f440, 139c4c9d, 1スレッドにbattlefield, await構文を活用して, 所謂コルーチンを実現しています, のようになっているわけです, a677f770, battlefields, 中身は, a677f6e0, thraed側の簡易コードイメージ, ゲームループ側のコードでは, コアの数だけ, a677f5e0, スレッドを作成し, 黒騎士と白の魔王での1バトルのホスティング単位で, 139dee94, a677f5a0, 0xbb, 例えばクエストバトルの場合, 最大4人のプレイヤーと敵モンスターが存在する, a677f560, 0xbf, 139defcb, a677f520, 0x95, doonefinalization, を複数詰め込みます, usersleep, a677f110, のasync, 数百ms遅れてもそこまで支障はないゲームデザインになっているため, サーバー側のクロックとクライアント側のクロックが別軸で動くことになりますが, 00007ffab434142e, 0000001ea677f300, 00007ffb1196d32a, 0000001ea677f2d0, ゲーム性として, sleepinternal, helpermethodframe, 00007ffb222b04c4, そのズレをどこまで許容できるかがデザイン上の肝となるでしょう, 黒騎士の場合は, 極度なネットワーク遅延以外はユーザーにストレスを与えません, クライアントを結果に送信する, リアルタイム通信のサーバーといっても, 0x8760, 様々です, 13e, クライアントから送られるコマンドを中継するだけのものもあれば, すべての処理をサーバー側で行うものもあります, のバトルは, タイミングによっては単に実行中なだけかもしれませんが, ファイナライザーがブロックされている可能性を疑えます, を実行中っぽいことがわかり, スタックから, syncblk, thinlock, という流れになります, 何らかのタイミングで溜まったコマンドを処理して, dedicated, 1f108dba, 0x33, eesleepex, threadによるゲームループのホスト, 139c4dc0, a677f0e0, 0x9a, sleepex, ここで問題になるのは, 13965263, a677f040, 何らかのタイミングをどのように発火させればよいか, ntdelayexecution, 例えばjavascriptではsettimeoutを延々と繰り返すのも, 一定間隔になるでしょうし, クライアントからのコマンドは一旦サーバー側で溜めておいて, a677f038, にも勿論, はあります, そのようにして構築された一定間隔の発火は, サーバーサイドにおけるゲームループといえるでしょう, timer, 何やら処理中であることがわかります, という文字列が見え, を実行するとclr上のスタックを確認できます, このようにマネージコード実行中であるスレッドに対しては, debuggeru2mcatchhandlerframe, 00007ffb13965976, サーバー側で処理を行うというのは, 202, a677f810, このawait可能なnextframeは独自に定義したものです, 400026f, 24d80, 回収されずにたまっていく一方となります, queueが一向に減らない状態となり, ファイナライザースレッドがブロックした状態になると当然ですがf, コマンドでファイナライザースレッドを特定します, 000001c651bee3e0, 18248, 000001c651becd10, 1d224, 000001c651bebe50, 496cc, 000001c651be0f70, 42834, 000001c651bdf910, 000001c651bde2b0, 時間の差分を取りながらsleep, 4c5c0, 000001c651bdcc50, 424b0, で処理回転に入るかどうかのチェックいれること, processcount, 000001c651bdb5f0, 1af00, 2b020, 000001c651bd8970, 5378, avg, gameloopthreadnumber, 2b220, 000001c1c62dbd60, ではファイナライザースレッドがブロックしているかどうかを調べるにはどうするかというお話です, 正確なゲームループを模す場合は, datadogに処理時間のモニタリングを入れておく, totalmilliseconds, attr, offset, increment, numstaticfields, numinstancefields, transparent, transparency, 102101, attributes, icriticalnotifycompletion, inotifycompletion, 00007ffb114b18c0, getresult, getawaiter, oncompleted, 00007ffb114b1968, parent, unsafeoncompleted, awaitを呼ぶとoncompletedシリーズが呼ばれて, gameloopthreadにactionを詰む, struct, 外から取り出すあれそれ, ループを回す間隔の曖昧さを許容する場合は, 0000000002000073, このままでも問題はない, 50754, 000001c4ca773fd0, ポイントになるのは, 71aff518, 71aff8a0, 0x54, 71aff860, 0xb6, waitforfinalizerevent, 139def64, 71aff820, 0x106, waitformultipleobjectsex, 13b21b1e, 71aff520, ntwaitformultipleobjects, 1f10a966, 1024, 71aff9e0, 013, waitforfinalizereventで次の呼び出しシグナルを待っているような感じでしょうか, 正常な場合にはこのようなスタック状態になるかと思います, ほぼ似た実装であることが期待できるcoreclrでもそんな感じなっている, ロックを最小限にすることと配列拡縮のコスト, 次にマネージコード上で無限ループに陥った場合のスタックです, そしてループ速度を稼ぐ, 二本の配列, 縮小しない, a677f900, をキューとして使うことで, 生threadを使う, const, a677f8d0, 71aff8e0, 71affa70, 000001c4ca773470, pendingthread, こいつが例外を吐くことは許さん, 2a020, 000001c1c484ea70, というのは呼び元で保証してくれ, 実際のコードでは外から終了できるような口を用意してある, apt, domain, maxstacksizeは小さめで構わない, alloc, threadobj, osid, hosted, deadthread, backgroundthread, 71affb10, unstartedthread, threadcount, となっていることがわかります, ここでは, 対象となるファイナライザースレッドが見つかったら先頭のidを確認します, はclrが知っている範囲の出力になります, でも一覧できます, なおスレッドは, このリストでは2番目にfinalizerと書いてあるのでこれがファイナライザースレッドです, を実行するとネイティブスタックを確認できます, スレッドを特定出来たら次にそのスレッドのスタックを見てみましょう, 71affc00, 71affbd0, 0x000001c1c6391000, 000001c5d559ced0, 1台辺りの性能限界というのは, 読めないようなものが出てきた場合には, ここで今回はメモリ関連の解析を行いたいので, レポートには以下のようなものが記録されます, ヒープのサイズ等の情報, メモリを多く使っているオブジェクトの一覧, ファイナライゼーションキューにあるオブジェクトの一覧, 怪しそうな項目の警告, ファイナライゼーションキューの情報なども出せるのはなかなかわるくないのです, まとめを出してくれるので大まかに状態の把握をするのには便利ですし, studioに比べて逆に細かいところは見れないのですが, あくまでレポートなのでvisual, とはいえwindbgでもかかります, また巨大なダンプファイルの解析にはとても時間がかかるので辛抱も必要です, お疲れさまでした, mhtml形式なうえに微妙に壊れることがあるのが若干難ありですが読めるのであればあまり気にしないことにしましょう, でダンプファイルを選択し, ただこのレポート, about, というクラッシュやハングを解析するルールもあります, ちなみに解析ルールとして, と同じようにスタックオーバーフローを確認してみましょう, 折角なので, 次のページ, これをビルドして実行すると無事死亡です, overflowにならなかったため少し変更しています, 前回のエントリーのコードをx64で実行したところryujitは賢いおかげだからなのかstack, グラニでは引き続きモバイルゲームの開発を行っていくほか, overflow, stack, という結果が表示されます, にチェックを入れ, で解析を開始します, をかけてみましょう, studioにsos拡張をロードできたのですがここ最近はそのようなことができなくなっています, ということがわかります, 上記の図では, 選択したオブジェクトが依存しているオブジェクト, つまり参照先を表示します, は選択したオブジェクトが参照しているオブジェクトへのツリー, entries, search, typeのカラムでアイコンが表示されるのでクリックすることで個々のオブジェクトを探っていくこともできます, 一覧のobject, もう少し突っ込んだ状態を調べたくなったら他のツールを検討します, studioでは開けないなど, これだけではわからない, これで開放されてなさそうだなといった情報をつかめる場合が多いでしょう, studioで見れば何となくあれが多いんだなとか, 以前はvisual, 解析が完了するとレポートが, 無料です, それだけではないのですが, ダンプファイルを突っ込むとまあまあいい感じにレポートを出してくれるという便利ツールです, debugdiagはmicrosoftが提供しているダンプ自動解析ツールです, を使ってみましょう, を起動すると以下のような画面が表示されます, インストールして, dotnetmemoryanalysis, files, data, explorer, internet, で開かれます, するとレポートに力強くerrorの文字と, その際作られたダンプファイルをdebugdiagに食べさせて, を持ち, methodtableはクローズ型みたいな, それはbitnessがあっていない, loadlibraryでライブラリが見つからない的なエラーになる場合がありますが, この際, mrの開発にも乗り出しています, それ相応の用語が出てくるので何となく押さえておくとはかどります, clrの中身が透けて見えるといっても過言ではない代わりに, 実際のwindbgを使うと, ヒープ, スタックじゃないやつ, なんかオブジェクトがあるところ, コールドな情報, 何らかコマンド実行してmtという項目に数字が出てきたらそれはmethodtableのアドレス, オブジェクトにはmtへの参照が書かれている, 例えばeeclassはジェネリクスのオープン型, 読み込むdllを変えれば対応できるはずですが前提にも書いた通りターゲットアプリケーションを64bitにするほうが手っ取り早いのでそうしましょう, mtからeeclassへの参照はセット, methodtableはeeclassを参照している, ホットな情報, どちらにも欠かせないのがネットワーク技術で, 普通は用事ない, これを元にクラスのリファレンスが解決される, ハンドル, メタデータのトークン, eeほにゃらら, engine, execution, を持っていてファイナライザーを呼び出す前のオブジェクトのキュー, 一度死んだやつ, finalizerの呼び出しを待っているオブジェクトのキュー, つまり64bitマシンで32bitのダンプを解析しようとしてる場合に出てきます, 64bitコンピューターで動作する32bitプロセスのダンプを読み込みたいしたいときの注意は最初に書いた通りです, レポートにはスレッドのスタックトレースなども出てくるので一発でダメなのがわかりますね, preview版ではmicrosoftストアからワンポチでインストールできます, guiでポチポチやって明らかにダメなものを発見できるお手軽解析ツールとして入れて置いておいても良いかなと思います, と言われるとそうですねという感じなのですが, studioでできるよ, それvisual, このあたり, まあしかしレポートなどが古めかしいの直したいのでオープンソースにしてほしいぞい, も立ち上げ, これも無料です, 最低限の操作だけ覚えていく感じです, net用のデバッガーではないというあたりから難易度の高さを誇り, いろいろと面倒な代わりに詳細な情報を得られるのが特徴です, 最後はハードコアなデバッガーwindbgで解析する方法です, 本質は変わっていないのでぬるま湯マネージコードマンには相変わらずハードコアです, 最近preview版として見た目がよくなったバージョンがリリースされたのですが, おてがるですごい, loadby, なんと, windbgのインストールですが, ファイルを選択してダンプファイルを開きます, open, windbgを起動したらfileメニューから, windbgであれこれ操作するのはここにコマンドを打ち込んで操作を実行していくことになります, とその横の入力エリアがコマンド入力欄となっていて, タブの下部にある, command, 中央の, ダンプファイルを開くと次のような画面になります, sos拡張をロードするには以下のコマンドを実行してください, ダンプファイルを開いてもそのままではマネージコードのデバッグはできないのでsos拡張をロードするところから始まります, はaを, だけ覚えていれば大体なんとかなります, 10やserver, もし間違ってprefer, 詳しくは触れませんが, architecture, current, support, does, と出るときはこれを疑います, sosも読み込んだのに, で開いて, platform, タスクマネージャー自体のbitnessとあっているかどうかを確認します, となっているかどうかを見て, 2016などであれば, と表示されているか, コンピューターで動作する32bit, 対象のプロセスが古いwindowsであればプロセス名に, タスクマネージャーでみて, sysinternalsのprocdump, を使うことで気にせずいい感じにとれるそうです, machine, ストック一覧を見る, processes, 引用をストックしました, capturing, tess, blogs, bitが有効なまま起動したといった状況で64bit, プロセスで動いているもののダンプをとって調べることになった際には次の点に注意してください, 32bit, 読者です, 今回はダンプを元にメモリ周りの状態を見ていく方法について調べたので少しまとめてみました, というスタックオーバーフローのような問題を調査する方法について触れましたが, このブログにて, そんなシチュエーションで役立つかもしれません, そんなときにはプロセスのメモリダンプを取得して解析することで問題の原因がわかりそう, ではメモリの使用状況やメモリリークなどを調査したいというケースがたまにやってきます, アプリケーションサーバーなど, 長い時間実行するようなアプリケーション, 限定公開記事のため引用できません, 引用をストックできませんでした, 合致していない場合であっても頑張れば解析できるとは思うのですが今回はそこに関して詳しくは触れません, と解析するマシンのbitnessは合わせておきましょう, まずダンプを取得する対象のbitness, 引用するにはまずログインしてください, prefer, 64bitマシン上では32bitで起動するので要注意です, が有効な状態でビルドされている場合, cpuでビルドしていても, 特にany, またダンプファイルの取得の仕方に関しては先のエントリーを参照してください, 利用できない場合があります, バージョンによっては若干手順が異なる, 1709の組み合わせです, framework, 今回の開発環境はvisual, 再度お試しください, ログイン, https, 32bitプロセスのダンプを取得するときは32bitのタスクマネージャーなどを利用する, aはbを参照している, この画面の右側のactionsの, サードパーティーのツールなどもありますが今回は標準的なツールのみです, 開発環境であれば特に追加のインストールも不要ですしお手軽ですね, studioではないでしょうか, メモリダンプをとった後とりあえず開いてみるならvisual, studioです, さてまずvisual, ここでは以下の単にオブジェクトを作るだけのプログラムでダンプをとってみたものを解析してみます, private, ここで止まっているときにダンプをとる, readline, studioでひらくと次のような画面が表示されます, というわけで上記プログラムからとったメモリダンプをvisual, を選択するとメモリ状態を表示するモードとなります, お手軽ですね, これら3つともmicrosoftの提供しているツールで, どのぐらいのメモリを使っているのかという情報を一覧表示できます, これでオブジェクトがどのぐらいあり, という二つのビューがあります, 一覧の下には, static変数, しかrootがないので, 逆を言えばここが残っているということは解放できないということでもあります, がなくなればgcが回収可能となりますし, という順でたどれるよということになります, 上の図の例では, 最終的にはgc対象となるルート, つまり参照元を表示します, は選択したオブジェクトからルートとなるオブジェクトへのツリー, recent, 最近はdotmemoryもダンプをインポートできるらしいとか, 下に進むにつれ詳細な情報が取れるとふんわりと考えてもらえればよいかと思います, が必要だということです, オブジェクトのルート, inc, つまり32bitプロセスをデバッグするにはwindbg, windbgでダンプを開くときはwindbgのbitnessを解析対象プロセスのbitnessに合わせる, links, メモリリークを調べたいのかで少し違いますが次のようなものをよく見る感じでしょうか, メモリ周りと言っても単純にメモリの使用状態を見たいのか, ダンプをとったはいいものの一体何を見ればいいのかを考える必要があります, 異常に増え続けていそうなものがあるのか, 何が大きく占めているのか, 各ジェネレーションごとのサイズなど, を調べる, リーク時も含む, メモリ使用量全般, gcで回収できないのは誰がつかんでいるせいなのか, ファイナライザースレッドがブロックされているとfinalize待ちが溜まる, 今回windbgに関してはコマンドがいろいろあるのでその部分が若干多めな解説です, ファイナライザースレッドがブロックされていないか, ファイナライザーの状態, メモリリークを調べる, メモリダンプをとってメモリ周りを調べるようなシチュエーションでは大抵はリークを疑っているケースがほとんどかと思います, もっとも, archive, 3つの解析ツールをご紹介します, studioを利用しましたが今回はそれに2つ加えて, 前回はvisual, 見たいところも何となくわかったとしてどうやって調べていけばよいのか, ダンプファイルを無事取得でき, どこのご家庭にもあるide, お手軽レポーター, ハードコアデバッガー, グラニはgrpcを中核にして, 限界が読みやすいところにもあります, 28022536, 1msかかる演算処理を0, 32227312, 12314440, 27216048, 5msにできれば, 250623072, 28643072, 18617496, 24296528, その2倍, 269818560, 28290896, 16091536, 3200フィールドホスティングできることになります, 12314264, サーバーサイドのコードはどうしても甘くなりがち, 31330472, 16513736, 30028920, どうせdbの処理時間のほうが大きいから誤差範囲でやっても意味がない, 36392760, 11994384, 24312736, 29711672, 12978040, 26680120, 困ったらサーバーを並べればスケールするでしょ, このbattleengineのような純粋なcpu処理で回しているコードの場合は, gen2, 25352648, 33517448, gen0, 5824, 576, 344, 2128, 560, 7672soh, 1016, 504, 8312soh, 10952, 2296, 黒騎士と白の魔王を支えるdatadogを使ったモニタリング, 398856, 2344, いうことを胸に刻んでおくと, 2064, 260060760, 7896soh, 2792, 疎かになりがちなサーバーサイドのcpu最適化のモチベーションがあがります, 3496, percentage, space, 2097619576, 252819744, 112874520, 210412040, 32706112, 12050624, 24502504, ここで, gen1, 相当大きな意味を持ってきます, 712, は決して速い言語ではない, 000001c5e5d946c8, 000001c5d6391000, 000001c5d6390000, 0x000001c5d6391000, 72699880, 0x4554fe8, 000001c24a8e5fe8, 000001c246391000, 000001c246390000, 0x000001c246391000, 0x000001c248645f38, 0x000001c2491b6448, 000001c1c487db90, 323174072, そういう視点で見ると, 0x13433eb8, 0xf20bed0, などがつかえそう, 000001c5c6391000, 000001c5c6390000, 0x000001c5c6391000, 2msぐらい重たくなる処理も簡単に書けてしまいます, 69369832, 0x4227fe8, 000001c1ca5b8fe8, 000001c1c6391000, 000001c1c6390000, この構成の良いところは, 0xfa036c8, 0x13f586b0, の使用割合です, 000001c655240000, lohが, small, soh, freeにあるpercentageカラムがくっついていて読みにくいですが, ジェネレーション別のアドレスを確認できます, コマンドでは各ヒープのサイズとアドレス, 2673725880, 0x9f5dd1b8, 347371576, 0x14b47838, 2097264, 0x200070, 000001c655441070, 000001c655241000, 267401184, 334857904, 0xff037e0, 000001c5f62947e0, 000001c5e6391000, 000001c5e6390000, 0x000001c5e6391000, 77873128, 0x4a43fe8, 000001c2cadd4fe8, 000001c2c6391000, 000001c2c6390000, 0x000001c2c6391000, 0x000001c2c81720a8, 0x000001c2c9131b70, 000001c1c48a74a0, 7960soh, 3368, では実際にwindbgを利用してメモリの状態を調べてみましょう, aのオブジェクトのアドレス一覧を得ることができました, 参照の残っている, 次に生きている, となります, 先の例では, 結果のmt列の値を指定します, には先ほどの, というコマンドを利用することで指定した型の生きているオブジェクトの一覧を出力できます, cedec講演の資料にもあったようにquakeのようなfpsでもありでしょう, あるいはその高レベルフレームワークである, 000001e5842c6d98, 000001e5842c6d68, 000001e583e12f18, ゲーム的な処理は一切存在しません, これで型, という型のオブジェクトの一覧を出力します, 一切存在しないが故に, 個々のオブジェクトを見つけることができたら次はそのオブジェクトがどこから参照されているのかを調べます, このコマンドに先ほどの一覧のaddressを渡せばそのオブジェクトの参照元を調べて出力してくれます, コマンドを利用します, オブジェクトのアドレスからルートへの参照を調べるには, 000001e593ef9aa8, 000001e593e15a08, 000001e5823817d8, handletable, 工夫次第でなんでもやれます, となっています, からのルートへの参照は, この結果では, その実証を, オブジェクトを見繕うために, 位置情報を送るようなmmorpgにもできるし, これはエントリポイントがなんやかんやで普段見えない何かなのであろうということが想像できます, 実際のところこれだけの情報であればvisual, その調査として出来そうな手順は以下のような感じでしょうか, 何が理由で残っているのかといったことを探るのが定石です, 一体何が多く残っているのか, メモリリークの原因を突き止める場合, gcに回収されていることを期待しているにもかかわらず残っているとか, 例えば数が想定外に多いとか, 別なオブジェクトを疑う, 正しければまたやり直し, 正しくなければ参照を切るなどを考える, 残っているのが正しいかどうかはアプリ次第, studioでの解析で利用したダンプを利用します, ここではvisual, コマンドに慣れる意味でも駆使して見てまわってみましょう, studioで見るのと大差なくめんどくさいだけといった感じなのですが, 今後もノウハウを築き上げていきます, 一覧を見て怪しそうな型を見つけます, ヒープにあるオブジェクトを型別で数とサイズを調べた結果を少ないほうから並べて出力してくれます, コマンドを使うと, サーバーサイドゲームループはかなり応用が効いて, まずは, 200321, 00007ffc3e0f64c8, 1966200, 00007ffc3e0f6310, 132956, 000001e5823ac0d0, 35304, 00007ffc9b5f7070, があって怪しそうなのがわかります, この例だとなんだかcountがやたら多い型, ちょっと例が悪かったですね, という部分が見えていて, 12320, 2381, 4003, 00007ffb11b4bd38, 419129744, 2381419, 22861536, 238141, 2286144, 23814, 498596, 2180, 000001c1c47fdf60, 355288, 00007ffb11b47070, 228576, 16048, 2652268, 00007ffab4265c50, 7744, 182, genericequalitycomparer, 00007ffb11b4b468, objectequalitycomparer, 00007ffb11b4bfb8, datadogに関しては, も参照ください, 空き容量を取得できます, では現在のヒープ領域とその中の世代別の使用量, 64384, 425512, 552, 2228320842, グラニではdatadogを用いて常に監視しています, studioの表示と比べると, もしメソッドの途中のローカル変数などに保持されている場合には以下のような出力になります, 00000255e4dc2e70, rsi, 00007ffc3e2004b7, 000000d7b20fec20, 2e4c4, のリリースにより, windbgというかsos拡張のコマンドはたくさんあるのでメモリ周りでよく使いそうなものをいくつかまとめておきます, まず第一歩として行えました, eab47c11, ff42f824, ffffd586, parameter, つまり型ごとのオブジェクトの数とその総サイズを取得します, extension, debugger, magiconion, 30319, framework64, c0000005, ちゃんと調べていない, もしかしたら何か組み合わせがあっていないとかかもしれません, 再度実行すると何もなかったかのように動くようになります, 初回はエラーが出るものの, というようなエラーが表示される, 初回コマンドを実行時に, 実際の1ループでの処理速度はモニタリング指標として非常に重要なので, 全てサーバー側のみで処理しています, load, コマンドや, 題材なのですが, 新しい製品も続々とでてきます, awsの進化は目覚ましく, apiと非常に相性が良いと思います, そして複雑なデータ構造を持っているaws, linqpad便利です, 僅かな差なのだし意味がない, そんなところをみるのはc, 的ではない, そこに貯めることで, その場合に最速なのはジェネリッククラスを一つ作って, typeをキーにして生成したデリゲートをキャッシュすることがよくあります, 特に動的コード生成においては, その具体的な例, そんな時にlinqpadを使うことで理解の手助けになるのではないでしょうか, マイクロベンチマークの測り方の説明をしたいと思っています, それを具体的な例にして, どちらかというと, 今回はパフォーマンス比較もそうなのですが, そこから取り出すケースも多いでしょう, typeをキーにした辞書を作って, 常に必ずしもtを元にして取り出せるわけではなく, テクニックの一つです, 覚えておきたいc, などでも使われている, パフォーマンスを追求するならそもそもc, 最速に取り出すことが出来ます, でなくていい, という意見には反対です, 使ったことのないapiを叩く機会も多いでしょう, メソッド一覧は実質の扱えるapiの一覧なので, フレームワーク側がtypeをパラメータとして渡してくることが多いため, 結果としては下記のようになります, selectmany, reservations, クライアントとサーバー間でのリクエスト, レスポンス通信の他に, サーバーサイドでもredisへのシリアライズ等に利用しています, binary, reading, 今回は, 2017年3月3日に行った社内での資料を公開します, に見るc, でのバイナリの読み方と最適化法, 短そうなインタンスidがあるのはご愛嬌, instanceidとprivateipが表示されています, モザイクモザイクしててなんのこっちゃって感じですが, これならすぐに書けます, この候補を見ることにより, 中々一発で書くのは難しいですが, reservationsから引っ張ってくるのもselectmanyで平坦化する必要があるのも, 非常に簡単です, わからなくなってもdumpの結果を見ながらコードを書けばいいので, dumpの結果からどんな構造になってるか分かるし, となったときも, こんな感じで何か特定の情報を取ってきたい, apiリストを確認する, そのクラスで扱えるメソッド一覧が全て候補して表示されます, linqpadの優秀な入力補完機能が利いてくれるため, ドキュメントを読まなくてもこれだけでapiを叩けるのでこちらも便利です, シンプルなものであれば, どんな値をパラメータとして渡す必要があるかということを把握することができます, apiで何ができるのか, それに応えるために非ジェネリックのapiが必要になってきます, フレームワークに統合する場合, select, dictionaryのルックアップはo, でも別に全然遅くありませんし, わざわざそのために非ジェネリックのhashtable使って気を使ったコードを書く必要もあまりありません, reader, multiple, あとはずっと読み込みしかないので, 書き込みは初回の一回だけで, 削除もないし, のようなシナリオにぴったりです, typeをキーにしてキャッシュしておく, これはコード生成用に最初の一回だけデリゲートを生成して, 読み込み側はスレッドセーフという特性を持っています, 書き込み時のみlockを使っていれば, akinshin, andrey, rider, の開発をしているようです, 現在はjetbrainsで, プロジェクトを主導しているのは, ある程度の部分をきちんと吸収してくれる重要な土台になっています, でタダだと思いがちですが, メモリ計測, jitの影響, ウォームアップ, stopwatchで囲めばokというものではない, マイクロベンチマークを正しくやるのはかなり難しいため, 数字の信頼性がずっと高くなります, writing, multi, のapiもあります, 他の言語と戦う際の土台でもあると思っています, の他に, 具体的には, hashtableの秘密, がよく使われます, スレッドセーフでなければならず, グローバルにあらゆるところからリクエストされる可能性があるため, typeをキーにして何らかの値を詰めていく場合, delegatecache, concurrentdctionary, 実は非ジェネリックのhashtableが最速です, net標準でこのケースにおいて最速の手法はconcurrentdictionaryではありません, こうした一つ一つの積み重ねは間違いなく意味を持ちますし, dictionaryよりも高速に動作します, これはlock不要のため, そこにはこう記されています, when, msdnのドキュメントを見てみましょう, serialized, 今回やってるのはかなりミクロな差を追求してるので, writers, そこは留意してください, provided, reads, 経由で呼ばなくする程度で2倍の差がつくってことは, allows, which, update, perform, つまりそれぐらいに僅差の違いでしかないので, one, instances, instanceid, オレオレベンチマークでやるよりも楽, これはそもそもawsのサーバーやサービスの状態が細かく扱える便利さ故の複雑性だと思うので, から扱う場合には, cuiで扱う場合には, windows環境でawsのapiを叩くときには, という経験を持っている方も少なくないんじゃないでしょうか, ちょっと何かしたいだけなんだけど意外と苦戦した, のような一見シンプルな操作だけでも意外とレスポンスの中身を掘っていかないとたどり着かないので, ec2インスタンス名の一覧を取得する, パッと見だとどう扱うべきなのか分かりづらいデータ構造になっているものが多いと感じます, apiのrequestに使うクラスやresponseで返ってくるクラスって結構ネストが深かったり複雑で, しかし一方で, とは感じます, これはもうそんなものと考えるべきなのかな, windows環境からでも全く問題なく扱えますし, に非常に助けられています, でのバイナリシリアライザではベストといえる仕上がりになっています, 複雑なものは複雑なのでどうしたものかなというのはあるのですが, linqpadって, linqpadに関しては下記の記事が良くまとまってます, linqpadを使ってみよう, 既に実プロダクトで動いているので, 今日からはじめる, 実行環境なのですが, vb等のエディタ, プロダクション環境で安心して使えるという実績も備えています, 要は軽量なc, likeな優れた入力補完, intelisense, パフォーマンスと機能拡張性の両面において優れた, 新サービス等への追従も早く, nugetによるパッケージ管理, とlinqでガリガリ弄って, symbol, dac, getting, 自前でうまく合わせないといけないようなのですが, 現在は完全に削られていて, とあったのに, 昔のドキュメント, expressのものだとうまく動かなかったり, 具体的な使用例から挙げています, コンソールアプリケーションのダンプだとうまく動くのですが, むしろ強力かもしれません, あるいはlinqpadのdumpなどで確認していったほうが, ウォッチウィンドウや, windbgのコマンドを覚えるぐらいなら, 仕事をする上で欠かせない便利な存在です, あとはやりたい放題です, で自由に解析できるなら, ともあれ, binaryreader, インフラ部の齋藤, という話をしたいと思います, 今回はawsのapiを扱うときにlinqpadを使うと何かと便利です, apiの便利さと複雑さ, powershell, グラニでの豊富なシリアライザへの知見に基づき開発された, tools, sdk, いつもお世話になっております, オブジェクトの構造を綺麗に整形して出力するdumpメソッド, errorするのに非常に便利な機能を持ったツールです, privateipaddress, あーこのプロパティからこの値取れるんだーといった感じでapiレスポンスの全体像を視覚的に把握することができます, managerを開きましょう, addnugetからnuget, f4を押すとqueryのプロパティが開くので, これを使ったインポートがお手軽でオススメです, すると候補が出るので, ctrl, コード上で赤くなってるクラス名にカーソルをあて, インポートはプロパティでもできますが, sdkを入れたらnamespaceをインポートしましょう, 戻り値であるdescribeinstancesreponseクラスの中身がdumpメソッドにより出力されます, するとdescribeinstancesが実行され, f5を押し実行してみましょう, namespaceがインポートできたらコードを実行する準備は完了です, 便利ですね, 更にinstancesっていうプロパティもlistになってて, awssdk, それ自体もlistになってて, reservationsっていうプロパティに何かec2の情報っぽいのが詰まっていて, describeinstancesresponseには何個かプロパティがあって, この出力結果から, という条件で試してみましょう, 起動状態を配列として取得する, プライベートip, 各ec2のインスタンスid, 実際には生のレスポンスを扱わないで整形して使うことがほとんどだと思うので, そして最新作の, 私の開発した, を全面的に採用しています, toarray, 採用範囲は, 開いたら, amazon, 小さいコードを書いてtry, 全然悪くない買い物だと思っています, 有料版, がオススメです, もし継続的に使用するのであれば, といった感じになってしまうので, 無料版だとコア機能がかなり制限されてしまってうーん, 本記事でも有料版が前提です, ということもあり, を購入しています, editionでインストールユーザー数無制限, premium, license, グラニでは, グラニでは愛用者が多いこともあり, 個人的にはこの便利さを得られるのであれば, elastic, linqpadでec2インスタンスの情報を取得する, では実際にlinqpadを使ってec2インスタンスの情報を取得してみましょう, programに変えて下記のようなコードを書きます, padを立ち上げqueryのlanguageをc, linq, accesskeyidとsecretaccesskeyは適当なものに変更してください, describeinstanceresponseの中身を見る, awssdkパッケージをインストールしましょう, managerを使用し, linqpadの機能の一つであるnuget, queryしましょう, cloudのパッケージを検索し, compute, というよりかは, net標準のベンチマークフレームワークといってもよく, 全体的に余計なコードがほとんどない状態なので, 独自の追加専用ハッシュテーブルを作る, microresolver, そこで自作のハッシュテーブルを作ることにより非ジェネリックでのパフォーマンスを向上させることに成功しました, という最速のdiライブラリを作成したのですが, 私は先日, そこから更に先を行ってみましょう, で完結してしまってもいいのですが, ではhashtableを使おう, そのなかの, キーポイントは幾つかあるのですが, lookup, fast, power, 具体的にx倍, tablemaskindex, hashcode, 性能向上は見込める気がします, とはいわないのですが, 良し悪しがあるので一概にビット演算にしたほうがいい, たったそれだけで大きな変化が見込めた, それなりの成果がありました, ハッシュテーブル内のバケットの参照方法を除算ではなくビット演算で済ますことで, addとgetしか用意しません, シナリオ的にremoveのサポートもなしで, という汎用ハッシュテーブルを作りましょう, 読み込みはロックフリーで最速, 全体的にスレッドセーフで, lockも内包して, ブレが多いため, みたいなことをこれで断言はできませんが, 追加側は必ずlockしなければならない, 2035, が最速ってことなので, 実際にどの程度最速なのか見てみましょう, 0では2倍速くなっている, などの例が挙げられていますが, 結果はこうなりました, それにならえば, 素朴にconcurrentdictionaryを使うことと比べて4倍の高速化が果たせています, 603, 4327, 283, 0145, performance, 1027, 少なくとも, improvements, 343, 5297, 0299, 921, 圧倒的改善, 637, 4833, 2倍弱高速化されています, 0273, 差分は, 経由でのgethashcodeとequalsを直呼び出しに変えたことです, dictionaryの結果が相対的にかなり悪くなったことが確認できます, というのも大変なので, ついでに, 2133, 計測しましょう, 1416, 506, 4558, 067, 1990, 522, 1154, 043, というようになってます, 良さそうじゃん, 更にブーストさせましょう, ので要点だけ摘むと, 読み込み中の参照には全く影響しない, だけ差し替えればいいので, 全てを新規に生成して, 追加時にキャパシティを超えてリハッシュが発生する際にも, 内部の連結リストの末尾に追加されるだけなら問題ない, 削除がないので, もし読み込み中に追加があっても, のフィールド一個だけに収めてあるからで, ハッシュテーブルの実体が, この実装でokの理由は, ライト側はlock内でやるようになってます, リード側がスレッドセーフで, 追加と読み込みは出来るけど削除は不可, keyはtypeで固定します, それではあんまりなので, ということですね, 5678, 0042, rehash, resize, 0741, failed, threadsafe, replace, 507, 2844, 0342, last, insert, 973, goto, 0487, わざわざ自作するというリスクを犯してまでやることなのだろうか, 962, override, 1723, 0491, 018, 3766, 6646, 705, typekeyhashtable, tkeyはtypeで固定する, なるほど, ぶっちけほとんど変わらなかった, 誤差範囲でむしろ遅い, おうふ, 9966, 5206, dapper, そんなことはなく違いが出るものだ, 815, 3286, 290, 0729, というのは気に留めておくと良さそうです, 007, 5089, l2989, sqlmapper, l17, markdownexporter, 特にstringがキーの場合, deserializeindirect, jil, そこから知りました, 私もdapperのコードを見ていたときに気づいて, その縁で知られているテクニックという感じもしますが, 作者はともにstackexchange勤務なので, dapperもjilも, nongenericの参照を要求します, coreではsystem, 最も使い道としてよくあるケース, hashtableが採用されています, なんて, 全文字列を舐めて算出するわけで, manualconfig, github, るわけではないですが, ベンチマーク結果を書く時に出力させとくとベンリ, を使いましょう, マイクロベンチマークには, 見ていきましょう, 実際にどの程度の違いがあるのか, 新たなるコピペ元として, ここに基本的なコンフィグを置いておきましょう, 毎回コピペ元を探してくる羽目になります, いきなり入れただけだとどう使っていいのかさっぱりわからなくて, 多機能ではあるのだけれど, benchmarkdotnetは非常に正しく, switcherは複数ベンチマークを作りたい場合ベンリ, 今回は一個だけなのでswitcherは不要ですが, 走らせる, デフォルトだと本気で長いので短めにしとく, memorydiagnoser, shortrunを使うとサクッと終わらせられる, のショートカット, warmupcount, targetcount, launchcount, shortrunは


Text of the page (random words):
clr finalizerthread finalizerthreadworker 0xbb 0e 0000001e a677f5a0 00007ffb 139666cc clr managedthreadbase_dispatchinner 0x39 0f 0000001e a677f5e0 00007ffb 1396660a clr managedthreadbase_dispatchmiddle 0x6c 10 0000001e a677f6e0 00007ffb 13a628ba clr managedthreadbase_dispatchouter 0x75 11 0000001e a677f770 00007ffb 13b2222f clr finalizerthread finalizerthreadstart 0x10a 12 0000001e a677f810 00007ffb 1f711fe4 clr thread intermediatethreadproc 0x86 13 0000001e a677f8d0 00007ffb 2227ef91 kernel32 basethreadinitthunk 0x14 14 0000001e a677f900 00000000 00000000 ntdll rtluserthreadstart 0x21 finalizeallobjects や callfinalizer という文字列が見え 何やら処理中であることがわかります このようにマネージコード実行中であるスレッドに対しては id e clrstack を実行するとclr上のスタックを確認できます 0 000 13e clrstack os thread id 0x8760 13 child sp ip call site 0000001ea677f1d8 00007ffb222b04c4 helpermethodframe 0000001ea677f1d8 system threading thread sleepinternal int32 0000001ea677f2d0 00007ffb1196d32a system threading thread sleep int32 0000001ea677f300 00007ffab434142e warning unable to verify checksum for consoleapp15 exe consoleapp15 g finalize c projects consoleapp15 consoleapp15 program cs 202 0000001ea677f728 00007ffb13965976 debuggeru2mcatchhandlerframe 0000001ea677f728 スタックから consoleapp15 g finalize を実行中っぽいことがわかり ファイナライザーがブロックされている可能性を疑えます タイミングによっては単に実行中なだけかもしれませんが また他にも同期ロックによるデッドロックなどがある場合にも引っかかります syncblk コマンドや dumpheap thinlock などがつかえそう appendix windbgでもっと簡単に詳しく windbgとsos拡張でいろいろ見れて便利 と思いきや 静的なフィールドの中身などをカジュアルに見ることはできません そこで sosex というwindbgの拡張を公開している方がいらっしゃるのでこれをありがたく使わせてもらいます load c path to sosex dll このsosexを使うと以下のようなsos拡張を強力にしたようなコマンドを使えるようになります mk マネージ アンマネージが混在したスタックトレースを表示 finq ファイナライゼーションキュー finalizerを持つオブジェクトのキュー を表示 frq f reachable キュー finalize呼び出しまちキュー を表示 mdt 指定した型やオブジェクトのフィールドを表示 万能 mlocks ロックの一覧 strings 文字列のダンプ 例えば mdt を使えば指定した型の静的なフィールドの一覧を表示できます 0 000 mdt consoleapp18 program consoleapp18 program s _values system collections generic list consoleapp18 a appdomain consoleapp18 exe 000001e5823c30c0 000001e583e12e70 system collections generic list 1 consoleapp18 a consoleapp18 他にもあらかじめインデックスを作っておくことで走査を爆速にするとか強い機能があるので使いこなせるとよさそうです 最近知ったのでほとんど使ってなかったのです ファイナライザーの実行を netアプリケーションコードから知りたい ファイナライザーの実行タイミングを netアプリケーションコードから知りたいということもあるかもしれません そんな時は gc registerforfullgcnotification と gc waitforfullgcapproach gc waitforfullgccomplete を組み合わせることで検出可能です ただしこの手法が有効なのはgcの設定が gcconcurrent enabled false の場合に限るので素直にパフォーマンスモニターなどに頼るほうが良いかと思います gc registerforfullgcnotification 99 99 _thread new thread while true var notification gc waitforfullgcapproach if notification gcnotificationstatus succeeded console writeline gc raised notification gc waitforfullgccomplete if notification gcnotificationstatus succeeded console writeline gc completed thread sleep 500 _thread start まとめ netアプリケーションを実行していると時に解決がなかなか難しい問題にあたることがあり そんなときメモリダンプが解決の糸口になる可能性があります もちろんダンプを眺めただけでは解決しない問題や 問題を発見したとしてもそもそもどうやって修正するのかというのはまた別の話です しかしながら解決の難しい問題は一つ一つ原因のようなものに見当をつけつつ追い詰めていく その為にダンプを調査できるようになっておくのは悪くないと思いますのでお役に立てば幸いです mayuki 2017 11 07 15 21 2017 10 12 string internによるunityでの省メモリ化ハック ctoの河合 neuecc です 常駐メモリは一ミリでも削りたい と思いつつも それなりに富豪に使ってしまっていて削るのに四苦八苦な日々ですが 削れる箇所はテクスチャなどリソース系だけではない c 側のマネージドなリソースもまた それなりに確保しているので 削ることは可能なのだ というお話です ものすごいメモリプロファイラ pa_resourcetracker を使う まぁ なにはともあれプロファイリングです メモリプロファイラで見てみましょう 実際の 黒騎士と白の魔王 の開発ビルドに流してみると うーん なかなか立派なstring確保量 そして大量の 通常攻撃 という同一文字列 スクリーンショットからは削ってしまってますが 右側には誰が参照しているかがわかる表示もついているので 犯人はひと目で分かり これは マスタデータに起因するものでした 独自開発のインメモリデータベース内にオブジェクトとして配置しているのですが 同一文字列が設定されたデータが大量にある と インメモリデータベースといっても 一行一行がオブジェクトとして独立しているだけなので 気の効いた圧縮などはかかってません さすがにザルすぎじゃね と言われるとすみませんというところでもあり しかしなるほど こりゃしょうがないね どうにもならないね というのはあんまりなので それをなんとかするのが後述するstring internです ところで この見慣れたようで見慣れないメモリプロファイラは pa_resourcetracker というもので いつものunity公式が提供しているmemoryprofilerを中国のエンジニアが魔改造したものです その改造は素晴らしく そもそも公式のかっこいいタイルマップなんかより このシンプルなリストビューのほうが100億倍欲しかったものなのですが と思います 更にスナップショット間のdiffなどもついているので メモリの増減が容易に確認可能という素敵さ il2cppでビルドした実機iosに接続すれば 詳細なマネージドメモリも確認可能 上のスクリーンショットはその手法で取得したものです 大変素晴らしい これを使って 現状と そして改善結果を確認していきましょう string internについて string intern はあまり見慣れないメソッドだと思います 詳細は wikipediaのstring interning の解説に譲るとして 多くの言語 php java python etc にも存在する文字列のインターン化に関する netのメソッドです 大雑把にいうと 文字列専用のハッシュテーブルといったところでしょうか 文字列は不変のため 同一の文字列は同一のメモリ領域を使うことで 全体的なメモリ使用量が節約されます c では文字列リテラルで記述された文字列は 必ずインターン化されています unsafeを用いて アドレスの位置を確認してみましょう il的にはldstr var str1 foo var str2 foo fixed void p1 str1 fixed void p2 str2 同一アドレスを指す console writeline intptr p1 46542800 console writeline intptr p2 46542800 勿論 true console writeline string isinterned str1 null true console writeline string isinterned str2 null true 大昔には string empty vs のどちらがいいか などという話もありましたが インターン化されてるのでメモリ的には別に一緒 むしろldstrとldsfldで命令的には のほうが有利 でもどうせjitで同じ結果になって一緒なので好みでok なお 私は のほうを好んで使います が結論です では 文字列リテラル以外で生成した場合は というと var str3 encoding utf8 getstring encoding utf8 getbytes foo var str4 new stringbuilder f append oo tostring fixed void p3 str3 fixed void p4 str4 str1とも異なるアドレスを指す console writeline intptr p3 47150368 console writeline intptr p4 47150432 文字列自体がインターンプールの中に存在しているか ではtrue console writeline string isinterned str3 null true console writeline string isinterned str4 null true referenceequalsもfalse console writeline string referenceequals str3 str4 false 同じ短い文字列であっても 異なるアドレス つまり二重に別のメモリ領域を使っているということになります では インターンプールから取得するにはどうすればいいか というと 簡単です インターンプールから取り出す or 登録する getoraddみたいなもの var str5 string intern str3 var str6 string intern str4 fixed void p5 str5 fixed void p6 str6 str1と同じアドレス console writeline intptr p5 46542800 console writeline intptr p6 46542800 referenceequalsもtrue console writeline string referenceequals str5 str6 true 無事 常駐の同一stringは同一メモリ領域を使うようになりました この場合 str3やstr4はgcで回収されます なお インターン化した文字列はずっとメモリ領域を確保し続け 解放する手段はないことに気をつけてください messagepack for c のimessagepackserializationcallbackreceiver string internが効果あるのは分かったが 適用して回るのは面倒くさいというか難しいというか無理というか システムの根っこでやらないとらちがあきません 黒騎士と白の魔王 では mastermemory という独自開発のインメモリデータベースを通しています が mastermemory自体は同じく弊社開発の messagepack for c でデシリアライズしたオブジェクトを登録しているだけです つまり システムの根っこはmessagepack for c のデシリアライザです というわけで デシリアライズ時に自動的にインターン化しましょう ここで便利に使えるのが imessagepackserializationcallbackreceiver です public class toarumaster imessagepackserializationcallbackreceiver public int id get set public string name get set public string description get set void imessagepackserializationcallbackreceiver onafterdeserialize デシリアライズ後のタイミングでインターン化してしまう this name this name null string intern this name null this description this description null string intern this description null void imessagepackserializationcallbackreceiver onbeforeserialize シリアライズ前に呼ばれる なにもしない これにより マスタデータに使われる型の 必要な 任意のプロパティだけインターン化することができました インターン化した文字列はずっとメモリ領域を確保し続け 解放する手段はない わけですが マスタデータはインメモリデータベースにアプリケーション起動時から終了時まで常駐し続けるので インターン化は有効な手段です なお imessagepackserializationcallbackreceiverの挙動は jsonutility の iserializationcallbackreceiver と同一です そのため もしjsonutilityを使っている場合で同じようにintern化したい時も 同様の対応が取れます 最後に 結果を見てましょう refsが1438と 見事にまとめられました 通常攻撃 以外にもまとめられたものは結構あったので それと他の部分でもインターン化が効率的なところに仕込んだ なんのかんのでトータルでは4mbぐらいは減ったっぽい たった4mb されど4mb まとめ まず言うと pa_resourcetracker は絶対的にお薦めです 本当に素晴らしい 最近 中国圏のゲームがストアランキングを賑わせていて 確かな実力を感じさせますが エンジニアリングも素晴らしく githubの中国圏でのみ賑わっているライブラリ類もまた 隠れた宝石といった趣があります string internは 存在は知っていましたが 使ったことはありませんでした あまりゲーム以外だと気にするレベルではない というのが実際ですが こうした古典的なc のテクニックも役に立つこともあるでしょう まぁ たまに ですが たまには たまたま 細かいc の動きに関してのプロファリングは microsoft clrの環境よりもunityのほうが 豊富なツール郡やil2cppの力もあって 把握しやすいように思えます unityはより深くc を追求していく環境としても かなり面白い環境なのは間違いないので 是非ともエクストリームc の沼にはまりましょう neuecc 2017 10 12 22 04 2017 08 09 ダンプ解析入門 visual studioでの可視化によるc トラブルシューティング ctoの河合 neuecc です ある日のこと アプリケーションが突然死 しょうがないのでサーバーに入ってイベントビューアーを見るとそこには 何の役にも立たない情報が並んでいるのであった こんなんじゃ原因も分からず どう対処もできない という時に役に立つのがダンプです ダンプさえあれば クラッシュ時の情報が手に入り 遥かに解決に向かいやすくなります ダンプ解析というとハードコアな印象もありますが 最近はツールが充実していることもあり やってみると意外とイージーです 幾つかの実例とともに どのように解析していくかを見ていきましょう ダンプを収集する クラッシュは突然に やってくるので まずはアプリケーションクラッシュと共に自動的にダンプが収集されるように設定しましょう ダンプファイルがなければ話は始まりません ここではwindows error reporting wer を使います マニュアルは collecting user mode dumps にありますが かいつまむとレジストリに手書きすると自動で収集するようになります では設定しましょう regedit exe を開き windows error reporting localdumps localdumpsキーが存在しない場合は新規に作ります そして dumpcount dumpfolder dumptype を設定 dumpcountは10 dumpfolderは適当なところ dumptypeはフル 2 にしました 再起動は必要なく これで設定は完了です スタックオーバーフローを解析する 一撃即死の定番といったらスタックオーバーフロー まずは簡単なコンソールアプリケーションを作りましょう namespace consoleapp93 class program static void hogehoge string s hogehoge s static void main string args hogehoge hoge なるほど即死 からの先程のdumpfolderには ちゃんと収集されています では こいつの解析をしましょう visual studio 2017を開き dmpファイルをドラッグアンドドロップすると ダンプファイルの概要が出ます この時点で 例外情報 スレッドのスタックがいっぱいです によりスタックオーバーフローが原因だとわかりますが 更にアクションから 混合でデバッグ あるいは マネージのみでデバッグ をクリックしましょう ソースコードレベルで丸わかり これ以上ないぐらい分かりやすいですね 完璧 と いうわけで pdbやソースコードがあればそこを組み合わせてクラッシュ時の箇所に止めてくれるので 一発です なのでできればそれらも合わせておきたいですが しかし 実際のクラッシュダンプ解析時にないよ という状況もままあるでしょう そんな時のケースも見てみます とはいえ勿論 ソースコードがあったほうが圧倒的に解決が捗ります ダンプを取得する際には pdbやその時のdll一式も含めてコピーし 手元にはその際のリビジョンに戻したソリューションファイルを開いておき そのvisual studio上でダンプの解析を始めると 簡単にダンプとソースコードを突き合わせることができます 一手間ではありますが 可能な限りその状態を作っておくと良いでしょう いったん releaseビルドし program cs は削除しておきましょう これでvisual studioがソースコードと突き合せられなくなります 見つかりません と 一気に情報量が減りました この状態で visual studioでのダンプ解析に役立つウィンドウがあり それらを開いていきます 一つはスレッドウィンドウ 実際のアプリケーションでは多数のスレッドが動いているはずで 各スレッドの情報や 切り替えての把握が重要になってきます もう一つが呼び出し履歴ウィンドウ まぁもうスタックオーバーフローだと一目でわかりますね これはスレッドウィンドウからのスレッド選択と連動しています そして最後に 欠かせない最も強力なものが並列スタックウィンドウ グラフ表示で 各スレッドとそのスタックの中身を表示してくれます 今回の例のような単純なものではあってもなくても変わりませんが 実際のアプリケーションでは100を超えるスレッドが動いているわけで それらが俯瞰して見えるのは非常に強力です スタックオーバーフローぐらい別に場所すぐ分かるんじゃないの と思いきや 特定条件が重なったときだけ発生する あるプルリクエストをマージしてから発生したのだけれどプルリクエストが巨大でちょっとどこだかわからない というかそもそもスタックオーバーフローなのかどうかもわからない とにかく突然死する といった状況下 なくはないというか普通にあると思います そんな時 ダンプの取得と解析は助けになってくれるでしょう 一発で原因を特定できます cpu100 やデッドロックを解析する クラッシュのほうがダンプ取得に関してはイージーで 実際に困るケースとしてはcpuが100 に張り付いてしまったりアプリケーションが止まってしまったりといった ハングするケースのほうが多いでしょう 自動で収集するには ダンプの取得自体がハイコストな処理なのでややリスキーです 瞬間的に100 なだけで復帰できるものが ダンプを取得しようとしたばかりに片っ端からアプリ停止して より深刻な障害に結びつく可能性があります 特定のタイミングで発生することが分かっている場合 たとえば高負荷時のみヤバくなる など なら 手動でタイミング見計らってダンプ取得するのもいいかもしれません 何れにせよ 場合によりマチマチで ベストな回答というのはありません 手動でダンプ取得する場合 最も簡単なのがタスクマネージャーから 右クリック ダンプファイルの作成 です 実際にasp netのデッドロックするシチュエーションを作り 解析してみましょう asp net mvcのテンプレートプロジェクトを作り indexを以下のように書き換えます public class homecontroller controller async task string getasync var str await new httpclient getstringasync http google com return str public actionresult index var s getasync result return view このコードはasync awaitによるデッドロックを引き起こします なぜ というとsynchronizationcontextが待ち合うからで 詳しくは以前に私が発表した以下のスライドに書いてあります httpclient詳解 或いは非同期の落とし穴について from yoshifumi kawai このコードを実行すると 無事ブラウザが真っ白で一向にレスポンスを返してくれなくなります ok ではダンプを取りましょう 手元で動かしている場合はiis expressがホストしているので iis expressのダンプを取ります これを開いて 混合でデバッグ から並列スタックで見ると 右下のグラフエクスプローラーで分かる通り 巨大なツリーになっていてハードコアでわけわからないです これはネイティブコードが混ざっているからで 正直ネイティブ部分はユーザーコードの外で見てもあまり分からないので 真の全体像を知るという点で使えないわけではない 省きましょう マネージドのみでデバッグ から始めるのが正解 すっきりしたグラフが得られました さて どこを見るべきか ですが こういう場合は長いやつが大抵正解 です homecontroller indexから来て manualreseteventslim wait で停止してそうな雰囲気があります これっぽいですね このようにウィンドウを4分割で並べておくと 把握しやすくて便利です デッドロック またはそれに近い状況は様々な原因で起こります 特に起きやすいと感じているのは プール関連 スレッドプールは伸張に時間がかかるため 用意されたプールを使い切ったあたりからアプリケーションのパフォーマンスが急速に低下します また コネクションプールも 通常最大数まで使い切ると 空きが出るまでは同期的に待ち あるいはタイムアウト その間は詰まったような動作をします それらが複合された結果 全体的に動かなくなってデッドロックと化す複合パターンもありえます そのようなときでのダンプと 大量の並列動作を俯瞰して見ることが出来る 並列スタックウィンドウ は 解析にあたって大きな助けとなるでしょう まとめ よりハードコアなダンプについては microsoftのサポートエンジニアの方々がdecode 2017で発表した ハードコア デバッギング windows のアプリケーション運用トラブルシューティング実践 というセッションならびに資料が大変詳しいです dumpの採取方法からwindbgによる解析 perfviewによるcpu負荷の解析まで 実にハードコアに網羅されています が しかし いきなりハードコアにやる必要はないんですね visual studioによる解析がもっともイージーだと思いますし 存外それで解決できるトラブルも少なくないと思います ハードコアに入るのは それで解決できなかったときからでよいわけです まずは簡単なところから入りましょう 更により高度な解析 もしくは自動化なども試みるなら プログラマブルなダンプの解析まで進んでもいいかもしれません microsoft clrmd を使うことで ダンプファイルをc で解析することが可能です 例えば先のiis expressのダンプをロードするには using var target datatarget loadcrashdump c users y kawai appdata local temp iisexpress dmp var version target clrversions 0 dacが見つからない場合もある microsoftのsymbolサーバーから落としてきたい var runtime version createruntime 以下runtimeを使ってあらゆる解析がプログラマブルにできる コンソールアプリケーションのダンプだとうまく動くのですが iis expressのものだとうまく動かなかったり 昔のドキュメント には getting the dac from the symbol server とあったのに 現在は完全に削られていて 自前でうまく合わせないといけないようなのですが ともあれ c で自由に解析できるなら あとはやりたい放題です windbgのコマンドを覚えるぐらいなら c とlinqでガリガリ弄って ウォッチウィンドウや あるいはlinqpadのdumpなどで確認していったほうが むしろ強力かもしれません neuecc 2017 08 09 16 49 2017 08 04 linqpadでaws apiを5倍理解する こんにちは インフラ部の齋藤 sri_1128 です 今回はawsのapiを扱うときにlinqpadを使うと何かと便利です という話をしたいと思います aws apiの便利さと複雑さ 普段 windows環境でawsのapiを叩くときには cuiで扱う場合には aws tools for windows powershell c から扱う場合には aws sdk for net を使います windows環境からでも全く問題なく扱えますし 新サービス等への追従も早く 仕事をする上で欠かせない便利な存在です いつもお世話になっております しかし一方で apiのrequestに使うクラスやresponseで返ってくるクラスって結構ネストが深かったり複雑で パッと見だとどう扱うべきなのか分かりづらいデータ構造になっているものが多いと感じます ec2インスタンス名の一覧を取得する のような一見シンプルな操作だけでも意外とレスポンスの中身を掘っていかないとたどり着かないので ちょっと何かしたいだけなんだけど意外と苦戦した という経験を持っている方も少なくないんじゃないでしょうか ただ これはそもそもawsのサーバーやサービスの状態が細かく扱える便利さ故の複雑性だと思うので これはもうそんなものと考えるべきなのかな とは感じます とはいえ 複雑なものは複雑なのでどうしたものかなというのはあるのですが 私は linqpad に非常に助けられています linqpadって linqpadに関しては下記の記事が良くまとまってます linqpadを使ってみよう 今日からはじめる linqpad 要は軽量なc f vb等のエディタ 実行環境なのですが intelisense likeな優れた入力補完 オブジェクトの構造を綺麗に整形して出力するdumpメソッド nugetによるパッケージ管理 等 小さいコードを書いてtry errorするのに非常に便利な機能を持ったツールです 無料版だとコア機能がかなり制限されてしまってうーん といった感じになってしまうので もし継続的に使用するのであれば 有料版 がオススメです 個人的にはこの便利さを得られるのであれば 全然悪くない買い物だと思っています グラニでは愛用者が多いこともあり enterprise license 950 00 premium editionでインストールユーザー数無制限 を購入しています ということもあり 本記事でも有料版が前提です linqpadでec2インスタンスの情報を取得する では実際にlinqpadを使ってec2インスタンスの情報を取得してみましょう まず linq padを立ち上げqueryのlanguageをc programに変えて下記のようなコードを書きます void main accesskeyidとsecretaccesskeyは適当なものに変更してください var accesskeyid hoge var secretaccesskey huga var ec2client new amazonec2client accesskeyid secretaccesskey regionendpoint apnortheast1 var response ec2client describeinstances response dump describeinstanceresponseの中身を見る 次に linqpadの機能の一つであるnuget managerを使用し awssdkパッケージをインストールしましょう f4を押すとqueryのプロパティが開くので addnugetからnuget managerを開きましょう 開いたら awssdk amazon elastic compute cloudのパッケージを検索し add to queryしましょう sdkを入れたらnamespaceをインポートしましょう インポートはプロパティでもできますが コード上で赤くなってるクラス名にカーソルをあて ctrl すると候補が出るので これを使ったインポートがお手軽でオススメです namespaceがインポートできたらコードを実行する準備は完了です f5を押し実行してみましょう するとdescribeinstancesが実行され 戻り値であるdescribeinstancesreponseクラスの中身がdumpメソッドにより出力されます この出力結果から describeinstancesresponseには何個かプロパティがあって reservationsっていうプロパティに何かec2の情報っぽいのが詰まっていて それ自体もlistになってて 更にinstancesっていうプロパティもlistになってて あーこのプロパティからこの値取れるんだーといった感じでapiレスポンスの全体像を視覚的に把握することができます 便利ですね 実際には生のレスポンスを扱わないで整形して使うことがほとんどだと思うので 各ec2のインスタンスid プライベートip 起動状態を配列として取得する という条件で試してみましょう void main var accesskeyid hoge var secretaccesskey huga var ec2client new amazonec2client accesskeyid secretaccesskey regionendpoint apnortheast1 var response ec2client describeinstances var result response reservations selectmany x x instances select x new x instanceid x privateipaddress state x state name value tostring toarray result dump 結果としては下記のようになります モザイクモザイクしててなんのこっちゃって感じですが instanceidとprivateipが表示されています 短そうなインタンスidがあるのはご愛嬌 こんな感じで何か特定の情報を取ってきたい となったときも dumpの結果からどんな構造になってるか分かるし わからなくなってもdumpの結果を見ながらコードを書けばいいので 非常に簡単です reservationsから引っ張ってくるのもselectmanyで平坦化する必要があるのも 中々一発で書くのは難しいですが これならすぐに書けます apiリストを確認する linq...
Thumbnail images (randomly selected): * Images may be subject to copyright.GREEN status (no comments)
  • この記事をはてなブックマークに追加
  • screenshot.751.jpg (358.8...
  • screenshot.752.jpg (77.3 ...
  • 引用して投稿する

Verified site has: 29 subpage(s). Do you want to verify them? Verify pages:

1-5 6-10 11-15 16-20 21-25 26-29


The site also has references to the 2 subdomain(s)

  engineering.grani.jp  Verify   grani.jp  Verify


Top 50 hastags from of all verified websites.

Recently checked links (by ScreenShot) on WebLinkPedia.

Screenshot of the main domain: kn.wikisource.orgScreenshot of the main domain: travertine-paving.com.auScreenshot of the main domain: basijnews.irScreenshot of the main domain: plugin-alliance.comScreenshot of the main domain: webclk.irScreenshot of the main domain: reel-scout.comScreenshot of the main domain: soravitgranville.comScreenshot of the main domain: still.euScreenshot of the main domain: adastra.ruScreenshot of the main domain: eleviina.blogspot.comScreenshot of the main domain: dd15.infoScreenshot of the main domain: dd15.infoScreenshot of the main domain: divahair.roScreenshot of the main domain: swk.deScreenshot of the main domain: swk.deScreenshot of the main domain: bigbearpestcontrol.comScreenshot of the main domain: lilyslittlelearners.comScreenshot of the main domain: chaudasie.comScreenshot of the main domain: andricevinstitut.orgScreenshot of the main domain: hatucam.wordpress.comScreenshot of the main domain: jokerharley69.showup-tv.comScreenshot of the main domain: mizubeya.comScreenshot of the main domain: luckypantsbingo.comScreenshot of the main domain: vnxam.netScreenshot of the main domain: antique-marks.comScreenshot of the main domain: toefljunior.iigvietnam.comScreenshot of the main domain: dochoistem.comScreenshot of the main domain: gosu.vnScreenshot of the main domain: ibw21.orgScreenshot of the main domain: genevalab.comScreenshot of the main domain: local.exactseek.comScreenshot of the main domain: jibres.irScreenshot of the main domain: hr.factcool.comScreenshot of the main domain: ecnetwork.jpScreenshot of the main domain: hempsapa.comScreenshot of the main domain: vapemeet.caScreenshot of the main domain: princessroyaltrainingawards.comScreenshot of the main domain: roksana95.showup-tv.comScreenshot of the main domain: dieelectric.orgScreenshot of the main domain: iguides.ru
Supplementary Information (add-on for SEO geeks)*- See more on header.verify-www.com

Header

HTTP/1.1 301 Moved Permanently
Server nginx
Date Fri, 29 Mar 2024 14:53:07 GMT
Content-Type text/html
Content-Length 162
Connection close
Location htt????/engineering.grani.jp/
X-Proxy-Revision 6a887aa
HTTP/1.1 200 OK
Server nginx
Date Fri, 29 Mar 2024 14:53:08 GMT
Content-Type text/html; charset=utf-8
Transfer-Encoding chunked
Connection close
Vary Accept-Encoding
Vary X-Epic-Device-Type,X-Epic-Flag-Variants,Accept-Encoding
Access-Control-Allow-Origin *
Content-Security-Policy-Report-Only block-all-mixed-content; report-uri htt????/blog.hatena.ne.jp/api/csp_report
P3P CP= OTI CUR OUR BUS STA
X-Cache-Only-Varnish 1
X-Content-Type-Options nosniff
X-Dispatch Hatena::Epic::Web::Blogs::Index#index
X-Frame-Options DENY
X-Revision 84c17382a0e01792a172378d0e10ca
X-XSS-Protection 1
X-Runtime 0.228830
Content-Encoding gzip
X-Varnish 267797660
Age 0
Via 1.1 varnish (Varnish/7.1)
Accept-Ranges bytes
X-Cache MISS
Cache-Control private
X-Proxy-Revision 6a887aa

Meta Tags

title="Grani, Inc."
name="robots" content="max-image-preview:large"
charset="utf-8"
http-equiv="X-UA-Compatible" content="IE=7; IE=9; IE=10; IE=11"
itemprop="name" content="Grani Engineering Blog"
itemprop="image" content="htt????/cdn.user.blog.st-hatena.com/default_entry_og_image/127482425/1514246779102529"
property="og:title" content="Grani Engineering Blog"
property="og:type" content="blog"
property="og:url" content="htt????/engineering.grani.jp/"
property="og:image" content="htt????/cdn.image.st-hatena.com/image/scale/9f27e1494096f3d7d73eab62a2a2ff704479d7c1/backend=imager;enlarge=0;height=1000;version=1;width=1200/https%3A%2F%2Fcdn.user.blog.st-hatena.com%2Fdefault_entry_og_image%2F127482425%2F1514246779102529"
property="og:image:alt" content="Grani Engineering Blog"
property="og:description" content="株式会社グラニはC#を中心として、ASP.NET、Unity、VR開発を行っています。"
property="og:site_name" content="Grani Engineering Blog"
name="twitter:card" content="summary_large_image"
name="twitter:image" content="htt????/cdn.user.blog.st-hatena.com/default_entry_og_image/127482425/1514246779102529"
name="twitter:title" content="Grani Engineering Blog"
name="twitter:description" content="株式会社グラニはC#を中心として、ASP.NET、Unity、VR開発を行っています。"
name="twitter:app:name:iphone" content="はてなブログアプリ"
name="twitter:app:id:iphone" content="583299321"
name="twitter:app:url:iphone" content="hatenablog:///open?uri=https%3A%2F%2Fengineering.grani.jp%2F"
name="google-site-verification" content="zo9sk6qpckUkZydjyvOLtUYN2Yr0YctWEljwf-znaMw"
name="viewport" content="width=device-width"

Load Info

page size56955
load time (s)2.1366
redirect count1
speed download26656
server IP54.199.90.60
* all occurrences of the string "http://" have been changed to "htt???/"

SEO From Wikipedia, the free encyclopedia
Search engine optimization (SEO) is the process of affecting the online visibility of a website or a web page in a web search engines unpaid results—often referred to as `natural`, `organic`, or `earned` results. In general, the earlier (or higher ranked on the search results page), and more frequently a website appears in the search results list, the more visitors it will receive from the search engines users; these visitors can then be converted into customers. SEO may target different kinds of search, including image search, video search, academic search, news search, and industry-specific vertical search engines. SEO differs from local search engine optimization in that the latter is focused on optimizing a business online presence so that its web pages will be displayed by search engines when a user enters a local search for its products or services. The former instead is more focused on national or international searches. and ADS Publishers From Wikipedia, the free encyclopedia
Advertising is an audio or visual form of marketing communication that employs an openly sponsored, non-personal message to promote or sell a product, service or idea. Sponsors of advertising are often businesses wishing to promote their products or services. Advertising is differentiated from public relations in that an advertiser pays for and has control over the message. It differs from personal selling in that the message is non-personal, i.e., not directed to a particular individual. Advertising is communicated through various mass media, including traditional media such as newspapers, magazines, television, radio, outdoor advertising or direct mail; and new media such as search results, blogs, social media, websites or text messages. The actual presentation of the message in a medium is referred to as an advertisement or `ad` for short.
Commercial ads often seek to generate increased consumption of their products or services through `branding`, which associates a product name or image with certain qualities in the minds of consumers. On the other hand, ads that intend to elicit an immediate sale are known as direct-response advertising. Non-commercial entities that advertise more than consumer products or services include political parties, interest groups, religious organizations and governmental agencies. Non-profit organizations may use free modes of persuasion, such as a public service announcement. Advertising may also be used to reassure employees or shareholders that a company is viable or successful., wall of links.


If you want to put something else on this wall, write to us.