<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://holthe-tveit.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://holthe-tveit.github.io/" rel="alternate" type="text/html" /><updated>2022-06-20T06:44:03+00:00</updated><id>https://holthe-tveit.github.io/feed.xml</id><title type="html">Tomas Eilev Holthe-Tveit</title><subtitle>Holthe-Tveit Blog</subtitle><entry><title type="html">Performance Profiling and Debugging</title><link href="https://holthe-tveit.github.io/Performance-Profiling-and-Debugging-in-dotnet/" rel="alternate" type="text/html" title="Performance Profiling and Debugging" /><published>2022-06-17T00:00:00+00:00</published><updated>2022-06-17T00:00:00+00:00</updated><id>https://holthe-tveit.github.io/Performance%20Profiling%20and%20Debugging%20in%20dotnet</id><content type="html" xml:base="https://holthe-tveit.github.io/Performance-Profiling-and-Debugging-in-dotnet/">&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;
&lt;p&gt;Profiling and Debugging are complementary techniques used to discover facts about what a given system &lt;strong&gt;is&lt;/strong&gt; doing and the performance characteristics of those actions’ .
We will focus on .net debugging and profiling here, but in any given system typically uses databases, OS level services etc, and therefore you will probably need to debug or profile these systems as well.
Profiling and debugging is huge areas, so this piece is focused on practical usage.&lt;/p&gt;

&lt;h1 id=&quot;debugging-net&quot;&gt;Debugging .net&lt;/h1&gt;
&lt;p&gt;Both .net (core) and .net Framework have extensive support for debugging. These tools can attach to a running process so you can step through the code as is runs. What detail you see are dependent on the build artifacts (debug vs release, symbols etc)
You are not only limited to running processes. You can also open a memory dump, and these dumps can be taken by a range of tools. Finally Dotnet-trace can also connect to a running process, but as the name suggest only tracing the process.&lt;/p&gt;

&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Visual Studio&lt;/li&gt;
  &lt;li&gt;VS Code&lt;/li&gt;
  &lt;li&gt;Rider, dotTrace, dotMemory&lt;/li&gt;
  &lt;li&gt;ANTS Profiler /ANTS Memory Profiler&lt;/li&gt;
  &lt;li&gt;WinDBG /WinDbg Preview&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/dotnet/diagnostics&quot;&gt;Dotnet-dump / Dotnet-trace&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Remote Debugger&lt;/li&gt;
  &lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;scenario-exceptions-being-thrown-by-production-system&quot;&gt;Scenario: Exceptions being thrown by production system.&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;(&lt;strong&gt;If Permitted&lt;/strong&gt; ) Get a memory dump. A memory dump will contain threads, stacks of treads, and heaps. All of these will both be managed and native, but our focus will be on the managed/.net side.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Alternatively, most IDEs support remote debugging. NB Secure this channel!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Start with Exception analysis. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!analyze&lt;/code&gt;
&lt;img src=&quot;/images/performance-profiling-and-debugging/windbg%20analyze.png&quot; alt=&quot;&quot; /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.foreach (ex {!dumpheap -type Exception -short}){.echo &quot;********************************&quot;;!pe ${ex} }&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Start with listing the current stacks. 
A good start hypothesis is that the active stacks in the dump will have recorded a hang. Check this out before moving on.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~* e !clrstack&lt;/code&gt; Lists stacks for all threads.
&lt;img src=&quot;/images/performance-profiling-and-debugging/windbg%20clrstack.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Your tool of choice may also automate checks for know issues like deadlocks. For WinDbg you can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!SyncBlk&lt;/code&gt;
&lt;img src=&quot;/images/performance-profiling-and-debugging/syncblk.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Check runaway threads
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!runaway&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!threadpool&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;profiling&quot;&gt;Profiling&lt;/h1&gt;
&lt;p&gt;Profiling is looking at how a system operates. This is typically used for performance reasons, as we assume that the behavior  is as designed.
Any code is generally either IO or CPU bound. Profiles may help you with both, but there are often differences in the tools and methods to profile between then. E.g. Jetbrains has dotTrace and dotMemory.&lt;/p&gt;

&lt;h2 id=&quot;cpu-bound-profiling&quot;&gt;CPU Bound profiling&lt;/h2&gt;
&lt;p&gt;Here we typically look at algorithmic  problems, measure and identify hotspots in the code. 
This can either be local or remote. Keep in mind that some profile methods may be very intrusive performance wise. This may not be acceptable in a production setting!&lt;/p&gt;

&lt;h2 id=&quot;memory-bound-profiling&quot;&gt;Memory Bound profiling&lt;/h2&gt;
&lt;p&gt;In managed/garbage collected runtimes like .net the memory is managed by the runtime, and as such you can only have a native memory leak. Such a leak can e.g. be a SqlConnection, File handle etc.
Typically, a “leak” in .net is rather that something is holding on to a reference, and it is thus not collected.
There is also another category that looks like a leak: not yet collected objects.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Very simplified&lt;/em&gt;:  class object instances are allocated on the heap while value objects are on the stack. 
Also, while strings have some value like behavior, remember that they are stored on the heap, and any modification (substring etc) is in fact a copy, and may exist on the heap for an extended time period.&lt;/p&gt;

&lt;p&gt;https://www.jetbrains.com/help/dotmemory/NET_Memory_Management_Concepts.html&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Garbage Collector (GC) is the part of the .NET framework that allocates and releases memory for your .NET applications.    &lt;br /&gt;
When a new process is started, the runtime reserves a region of address space for the process called the managed heap. &lt;br /&gt;
Objects are allocated in the heap contiguously one after another.&lt;br /&gt;
Memory allocation is a very fast process as it is just the adding of a value to a pointer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Any object larger than 85KB are store separately on the Large Object Heap (LOH). This is not compacted during normal garbage collection. The LOH will thus get fragmented over time.&lt;/p&gt;
&lt;div class=&quot;mermaid&quot;&gt;
flowchart LR
    allocation(Allocation)
    subgraph gen0
        direction TB
        0_allocate_1(allocate some) --&amp;gt; 0_allocate_n(allocate more) --&amp;gt; 0_full(full) --&amp;gt; 0_GC_generation(Garbage collect Gen 0)
        end
     subgraph gen1
        direction TB
        1_allocate_1(moved into gen1) --&amp;gt; 1_allocate_n(moved even more into) --&amp;gt; 1_full(full) --&amp;gt; 1_GC_generation(Garbage collect Gen 1)
        end
    subgraph gen2
        direction TB
        2_allocate_1(moved into gen2) --&amp;gt; 2_allocate_n(moved even more into) --&amp;gt; 2_full(full) --&amp;gt; 2_GC_generation(Garbage collect Gen 2)
        end
    loh(Large Object Heap)
    allocation  --&amp;gt;  gen0 &amp;amp; loh
    gen0 -- still in use--&amp;gt; gen1
    gen1 -- still in use--&amp;gt; gen2
    
&lt;/div&gt;

&lt;h3 id=&quot;finding-your-roots&quot;&gt;Finding your roots&lt;/h3&gt;
&lt;p&gt;A key factor in memory pressure is holding on to references as short as possible. The sooner the last reference to an object is released the quicker an object &lt;strong&gt;can&lt;/strong&gt; be garbage collected.
Be cautious when adding delegates, event handlers etc to global or static scoped objects or methods. NB This also includes what singleton scoped dependency that is injected into your code. Most unwanted memory is due to this.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!DumpHeap -stat&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!DumpHeap -stat -type SomeType.OrAnother&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;rent-not-allocate&quot;&gt;Rent, not allocate&lt;/h3&gt;
&lt;p&gt;For large allocation it will typically be much faster both on allocation as well as collection to rent an array from ArrayPool/ArrayPool.Shared. There are also more advanced allocation schemas that can be used like an &lt;a href=&quot;https://mgravell.github.io/Pipelines.Sockets.Unofficial/docs/arenas.htm&quot;&gt;Arena Allocator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/performance-profiling-and-debugging/you%20do%20not%20need%20to%20collect%20what%20you%20do%20not%20allocate.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;measure&quot;&gt;Measure&lt;/h3&gt;
&lt;p&gt;Measure using &lt;a href=&quot;https://benchmarkdotnet.org&quot;&gt;Benchmarkdotnet&lt;/a&gt;, &lt;a href=&quot;https://www.jetbrains.com/help/rider/Dynamic_Program_Analysis.html&quot;&gt;Rider Dynamic Program Analysis&lt;/a&gt;, DotMemory, Visual Studio etc.
Go for large and frequent allocations and iterate.&lt;/p&gt;</content><author><name></name></author><summary type="html">Intro Profiling and Debugging are complementary techniques used to discover facts about what a given system is doing and the performance characteristics of those actions’ . We will focus on .net debugging and profiling here, but in any given system typically uses databases, OS level services etc, and therefore you will probably need to debug or profile these systems as well. Profiling and debugging is huge areas, so this piece is focused on practical usage.</summary></entry><entry><title type="html">My thoughts on Agile Organizations</title><link href="https://holthe-tveit.github.io/My-Thoughts-on-Agile-Organizations/" rel="alternate" type="text/html" title="My thoughts on Agile Organizations" /><published>2022-05-19T00:00:00+00:00</published><updated>2022-05-19T00:00:00+00:00</updated><id>https://holthe-tveit.github.io/My-Thoughts-on-Agile-Organizations</id><content type="html" xml:base="https://holthe-tveit.github.io/My-Thoughts-on-Agile-Organizations/">&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;
&lt;p&gt;These reflections and observations are based on my experiences in multiple projects and organization and heavily inspired by Alex Cowan’s &lt;a href=&quot;https://www.coursera.org/specializations/uva-darden-digital-product-management&quot;&gt;Digital Product Management&lt;/a&gt; course.&lt;/p&gt;

&lt;h2 id=&quot;what-is-agile&quot;&gt;What is agile?&lt;/h2&gt;
&lt;p&gt;Agile is the realization that change is inevitable. An organization should optimize for change and make change easy as possible. This does not only apply to technical aspects. It is just as important- if not more- in the organizational structure. After all you cannot escape the organization:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.
— Melvin E. Conway
&lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_law#cite_note-Conway-2&quot;&gt;1&lt;/a&gt; &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway%27s_law#cite_note-3&quot;&gt;2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just having agile is of limited value if these interact and deliver in a non-agile organization. What are some indicators of such?
·        The area of responsibility vs control of change that a team has.
·        Forced inter-team communications/collaboration.&lt;/p&gt;
&lt;h3 id=&quot;responsibility-vs-control&quot;&gt;Responsibility vs control&lt;/h3&gt;
&lt;p&gt;The mismatch between responsibility and control often manifests with teams that are responsible for a thin slice of layers, whether one layer or a few layers of a value chain and does not control enough of the vertical slice. This leads to the team being dependent on other teams for its day-to-day business and significantly blocks changes.&lt;/p&gt;
&lt;h3 id=&quot;excessive-forced-inter-team-communication&quot;&gt;Excessive forced inter-team communication&lt;/h3&gt;
&lt;p&gt;Forced in the meaning that the team needs resources outside the team to do its job/purpose. It will not be practical or even desirable to eliminate this completely. If this is excessive then it is an indicator that the organization may benefit from changes.&lt;/p&gt;

&lt;h2 id=&quot;solutions&quot;&gt;Solutions&lt;/h2&gt;
&lt;h3 id=&quot;what-not-to-do&quot;&gt;What not to do&lt;/h3&gt;
&lt;p&gt;Don’t do a massive reorganization. Especially if this is against the will of the affected persons. Have we not learned that huge, big-bang releases are bad?&lt;/p&gt;
&lt;h3 id=&quot;what-to-do&quot;&gt;What to do&lt;/h3&gt;
&lt;p&gt;We should approach this scientifically in a hypothesis-driven process, where we acquire information: both facts and opinions from team members and stakeholders and together state hypotheses. These will need to be tested as isolated and on as small scale as possible.&lt;br /&gt;
For your next multi-team project or initiative: can you create a team (if only temporarily) or an integrated working group and try to verify the desirability, viability and feasibility of the proposed feature, project, or product.&lt;/p&gt;

&lt;h2 id=&quot;try-learn-and-improve&quot;&gt;Try, learn and improve!&lt;/h2&gt;</content><author><name></name></author><summary type="html">Intro These reflections and observations are based on my experiences in multiple projects and organization and heavily inspired by Alex Cowan’s Digital Product Management course.</summary></entry></feed>