quiz_banner

What do you know about .NET memory management? Should you care at all? Yes, it is all managed and automatic and the Garbage Collector takes care of everything. That’s a great achievement of managed runtimes in general – they provide this super nice abstraction of memory that is just there and we do not need to think about it at all, right?

Well, yes and no. For sure you may for years develop business applications earning money and do not touch a topic of .NET memory management at all. I’ve been there too. But, there is always more. There is always some edge case, some scalability problem, a memory leak or just not efficient resources utilization (wasting money💸). I’m not here today to convince you to that, tough. There will be time for this 🙂

Today I just wanted to invite you to my new initiative – a small quiz about .NET memory management. 32 questions that may, or may not, shed some light on you in the context of this topic:

👉 Take a quiz 👈

Share your result, elaborate about questions! And as you see at the end, you can subscribe to the newsletter where I’ll be providing explanations of correct answers for every question.

And yes, this is a beginning of a bigger initiative https://dotnetmemoryexpert.com – more about it soon. In general, more and more GC- and memory-related content is coming!😍

 

 

I’ve decided to make a series of at least 8 free weekly-based webinars about in-depth implementation details of the .NET GC and… I’m super happy with it! Why the idea? Many my other activities are about more practical “.NET memory management”, like my book or workshops/trainings/consultancy I gave. But during all this practical-oriented events there is always not enough time to explain in details how .NET GC is implemented. Obviously, I always explain some concepts and algorithms, to the level that helps in understanding the whole concept. But not with the level of details that I am satisfied.

Hence the idea – make a separate content that will be just as deep as I like 🙂 So, I will cover details on the level of bits, bytes and source code, not only on the level of the overall algorithm description.

The first episode was yesterday, feel invited to watch:

Continue reading

logo-thinkific

Testing shows the presence of errors in a product, but “cannot prove that there are no defects” – you probably know that quote. I remember so many hours spent on debugging those little, mean bugs hidding deeply in the code edge cases. But what’s worse, I remember even more hours trying to understand and reproduce an error that happens only in production environment. Here’s the first top 5 most popular issues I’ve met during last years:

  • app hangs due to deadlocks (in the app or external library)
  • memory issues like memory leaks, long GC pauses or high CPU usage due to the GC
  • swallowed exception preventing some logic, with no logs available
  • threading issues like thread-pool starvation
  • intermittent errors due to the resources shortage, like running out of sockets or file handles

BTW. And what’s yours top 5?

Continue reading

Imagine we have a simple class, a wrapper around some array of structs (better data locality etc.):

Now, I would like to have an efficient access to every element. Obviously, a trivial indexer would be inefficient here, as it would return a copy of the given array element (a struct):

Luckily, since C# 7.0 we can “ref return” to efficiently return a reference to a given array element which is super nice (refer to my article about ref for more info):

Here, 99.9999% of devs will stop and will be satisfied with the semantics and performance results. But… if we know we will call it tremendously often, can we do better?!

First of all, let’s see what is being JITted by the .NET Core x64 runtime (5.0rc) when accessing 9th element (index is 8):

To those who know assembler a little, it may be clear what is going on here. But let’s make a short summary:

  • we see a little of “stack frame” creation here (sub/add rsp) – could we get rid of it in such a simple method?
  • we see bound check in line 4 (cmp the index to 8) to check if we are accessing an array with a correct index – could we get rid of it because we trust our code? 😇

Disclaimer: Getting rid of bound checks is very risky and the resulting dangers probably will overcome the performance benefits. Thus, use it only after heavy consideration, if you are sure why you need it and you can ensure caller’s code will be correct (providing valid indices).

To continue, we will be walking on thin ice of unsafe code now.

The first idea is to use Unsafe.Add to provide kind of “pointer arithmetic” – add an index-element to the first element:

The “problem” here is, it produces almost identical results because _array[0] is still a bound-checked array access (and we don’t get rid of stack frame too):

Hence, the non trivial question arises – how to get the address/ref to the first element of an array?

We could think of doing some Span-based magic (to use MemoryMarshal.GetReference):

But you can probably feel it – it produces even slower and bigger code (Span creation handling etc.) while still bound check will be there (Span is “safe”).

So, we need somehow to find a better way of getting an address of the first array’s element. The thing is, the internal structure of the array type is an implementation detail (although well-known). How can we overcome that?

The idea is… to rely on that implementation detail. This approach is being used by DangerousGetReferenceAt method from Microsoft.Toolkit.HighPerformance package maintained by Sergio Pedri. DangerousGetReferenceAt source code explains it well:

So, we are casting (reinterpreting) an array reference as a reference to some artificial RawArrayData class, which has a layout corresponding to an array layout. Thus, getting “data” reference is now just trivial. No bound checks at all!

The good news is this method has been ported to .NET 5! So, in .NET 5.0rc we can already use MemoryMarshal.GetArrayDataReference which does exactly the same thing:

Thus, without any external dependencies our code in .NET 5 may be rewritten to:

And the resulting code is indeed much more lightweight:

No bound-checks, and as an additional reward from the method simplicity – no stack frame.

Benchmarks are indeed showing a noticeable (well, in ns order of magnitude) difference:

Which simply means, we are now about 5x faster than with the initial solution!

Disclaimer #2: Approach taken here with the usage of GetArrayDataReferece is super dangerous. As Levi Broderick, one of .NET framework developers, said: “Also, read the method documentation. It does more than remove bounds checks; it also removes array variance checks. So it might not be valid to write to the ref, even if the index is within bounds. Misuse of the method will bite you in the ass, guaranteed.”  Moreover, documentation clearly states that “a reference may be used for pinning but must never be dereferenced” 😇

Sync over async in .NET is always bad and there is no better advice than just to avoid it. What does “Sync over async” mean exactly? It happens if you synchronously wait on an asynchronous operation result with the help of .Result, .Wait or similar. Why is it bad? First of all, it blocks (wastes) one thread to wait on a result – which may lead to threads starvation. But even worse, it may deadlock your operation and (sometimes) the whole application.

Probably you’ve heard all that previously. I just wanted to present a picture, “worth a thousand words“, to explain why does it happen.

synchronizationcontext_winforms_nestedsyncThere is a concept of SynchronizationContext in .NET – an abstraction that knows how/where schedule a work item (like an async/await continuation). When you await something, SynchronizationContext is being captured. And when continuation is going to be run – we use SynchronizationContext to run the continuation “somewhere”. SynchronizationContext implementation may be different in various scenarios (console, UI, web, mobile applications), because there are various needs to “synchronize” work items. The main example is a GUI-based application. When we start an asynchronous operation on the UI thread, we expect its continuations will “return” to the same thread.

But, if we .Result that operation, the main UI thread is blocked waiting on the result, so it is not able to process anything (including mouse/keyboard events). So there is no way continuation (that would set the result) may run, thus we endlessly wait for the result – deadlock.

synchronizationcontext_winforms_configureawait

That’s why ConfigureAwait helps – it allows to say “I don’t care about scheduling continuation to the original (captured) context“. Thanks to that asynchronous operation continuation is scheduled to a different thread (thread pool’s) and sets the result with no problem. This resumes the main UI thread, and there is no deadlock.

That was just two simple drawings. If you’d like to know more, refer to a great ConfigureAwait FAQ by Stephen Toub.

Again, all this is just a work for a much bigger project, which is awesome Async Expert on-line course about asynchronous and concurrent programming in .NET. If you found it interesting, stay tuned by subscribing to the newsletter on the above-mentioned page!

It is said that picture is worth a thousand words, and I agree. That’s why I like preparing technical drawings to explain various concepts. So, here it is – a short story of how async/await works in .NET.

thereisnothread

The main power behind async/await is that while we “await” on an ongoing I/O operation, the calling thread may be released for doing other work. And this provides a great thread re-usability. Thus, better scalability – much smaller number of threads is able to handle the same amount of operations comparing to asynchronous/waiting approach.

The main role here plays so-called overlapped I/O (in case of Windows) which allows to asynchronously delegate the I/O operation to the operating system, and only after completion the provided callback will notify us about the result. The main workforce here is so-called I/O completion port (IOCP).Continue reading

poh01

In the upcoming .NET 5 a very interesting change is added to the GC – a dedicated Pinned Object Heap, a very new type of the managed heap segment (as we have Small and Large Object Heaps so far). Pinning has its own costs, because it introduces fragmentation (and in general complicates object compaction a lot). We are used to have some good practices about it, like “pin only for…:

  • a very short time” so, the GC will not bother – to reduce probability that the GC happens while many objects were pinned. That’s a scenario to use fixed keyword, which is in fact only a very lightweight way of flagging particular local variable as a pinned reference. As long as GC does not happen, there is no additional overhead.
  • a very long time”, so the GC will promote those objects to generation 2 – as gen2 GCs should be not so common, the impact will be minimized also. That’s a scenario to use GCHandle of type Pinned, which is a little bigger overhead because we need to allocate/free handle.

However, even if applied, those rules will produce some fragmentation, depending how much you pin, for how long, what’s the resulting layout of the pinned objects in memory and many other, intermittent conditions.

So, in the end, it would be perfect just to get rid of pinned objects and move them to a different place than SOH/LOH. This separate place would be simply ignored, by the GC design, when considering heap compaction so we will get pinning behaviour out of the box.Continue reading

Mobius Overview

.NET application is “just” a piece of CIL bytecode to be executed by the .NET runtime. And .NET runtime is “just” a program that is able to perform this task. It happens that currently .NET Framework/.NET Core runtimes are written in C++. I am also fully aware of CoreRT that was .NET runtime with many parts rewritten to C# (like type system) but still, crucial parts (including JIT compiler and the GC) were left written in C++.

But what if we write .NET runtime as… .NET application? Is is possible at all? I mean, literally no native/C++ code, everything running as .NET Core application written in C#? Does this sound like kind of inception and infinite recursion? It would require running one .NET runtime on the top of another .NET runtime, right?

I decided to check it out and that’s how Mobius runtime idea has been coined! Yeah, I know it sound strange and I do not expect it will be anything close to production ready thingy in the nearest century. I am fully aware of the amount of code needed to be written to make full .NET runtime. However, I found it interesting to validate such idea and I find it small usages as well. Imagine a NuGet package with the separate runtime that you can add to your application 😉

Continue reading

GC posters

In short words, I’ve prepared two posters about .NET memory management. They provide a comprehensive summary of “what’s inside .NET GC”, based on .NET Core (although almost all information is relevant also for .NET Framework).

The first shows a static point of view – how memory is organized into segments, generations, what are the roots and etc.:

Poster I

The second shows a dynamic point of view – how GC threads are working and what GC modes are available:

Poster II

 

You can download them for FREE in vector PDF format from my https://prodotnetmemory.com site. Take it and print it!

 

 

bothgamesbanner_white

2 Developers from Poland join forces to publish their IT-related card games: from Devs to Devs – OutOfMemory and IT Startup!

Each of us already has a published book and now we want to share some knowledge with fun games! Remember all the original 151 Pokemon names? How about playing a game that lets you remember something useful: like what technologies are beneficial to learn to be a better Developer! One of the games is already published in Poland and sold over 3k copies (so we how already some publishing know how). Now we want to start a company and publish 2 of our IT related card games worldwide in English.

Have fun while playing our print and play prototypes!

We plan to publish the games as one company on Kicktarter in Q1 2020.

Continue reading