Hi and welcome to the third episode of the .NET GC internals! Yesterday is was again 1.5h of talking about the Mark phase, this time in its Concurrent flavour. Most of the time I’ve described the solution and implementation of it to two problems:

  • Problem #1 – how to mark an object while being used? – in non-Concurrent Mark phase MethodTable pointers is used for this. But now, while the application is running and may access this pointer, it is not the best place ever 🙂
  • Problem #2 – how to get a consistent view while references are changing? – even more difficult problem, as the GC tries to discovers what is reachable while references between objects are constantly changed by the application

gcwebinar12

Enjoy watching the recording on YouTube and if you have any questions, do not hesitate to ask!

As usual, you can get the slides from our goodies page.

And do not forget to join Wednesday, February 10, 7PM CET – this time I’ll cover Plan phase, describing such internal stuff like “plugs”, “gaps”, “brick tables” and more!

Hi and welcome to the second episode of the .NET GC internals! Yesterday is was 1.5h of talking about the (non-concurrent) Mark phase. The one responsible for discovering which object are “reachable” and which may be garbage collected. I’ve covered topics like object graph traversal algorithm, the pinning and marking flag, the mark stack and mark list data structures. And obviously, some deep dive into the gc.cpp at the end.

gcwebinar07

Enjoy watching the recording on YouTube and if you have any questions, do not hesitate to ask!Continue reading

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

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

outofmemory

In the previous post, I’ve announced that I’m working on a card game for .NET developers. In this post, I would like to make yet another one exciting announcement – OutOfMemory! game will be Kickstarted and… even more – it will be not alone! As around at the same time as I planned, another IT-related card game was going to be announced, we decided to join forces and benefit from such synergy, instead of stepping on each other toes. This decision was quite obvious – both we are developers, both we are from Poland and both we are planning to offer IT-related card game 🙂

So, I am pleased to announce that since today we are joining our design, marketing, and social media forces, which eventually will result in a joined Kickstarter campaign, about two game cards at once:

  • OutOfMemory! game for .NET developers (and I’m strongly considering other languages/ecosystems as an option) – in short, a game about building an application from features, with a strong emphasis on their performance and memory consumption
  • IT Startup game – about building IT company, by hiring developers and taking care of their burnout. This project has been already successfully crowdfunded here in Poland and now its author – Mateusz Kupilas – wants to expand into the international market.

With our joined social media channels and Mateusz experience of selling over 2500 IT Startup games, we believe everyone will benefit – and mostly, potential players!

As a project supporter, you will have an option to support one of those games or both (with a proper discount, of course!). We even considered designing both games in a way allowing to combine them into one, if one wishes. But this idea is currently postponed.

When both games will show up on Kickstarter? Not in the upcoming months, for sure. Most probably, at the beginning of February 2020. Since then there will be a lot of time to polish game design and build some community around prototypes.

If you want to learn more about IT Startup, please feel invited to visit its dedicated page at http://playitstartup.com/, or follow its social media channels on Facebook It Startup – The Card Game page or on Twitter @playitstartup. Mateusz writes also about our cooperation on his blog (in Polish) – https://www.javadevmatt.pl/lacze-sily-z-konradem/

1

During our trip around managed pointers and structs, we get the last topic to discuss – readonly semantics. Thus, we touch today topics like readonly structs and readonly paremeters.

Readonly ref variables

Ref types are quite powerful, because we may change its target. Thus, readonly refs were introduced in C# 7.2 that controls the ability to mutate the storage of a ref variable.
Please note a subtle difference in such context between a managed pointer to a value type versus a reference type:

  • for value type target – it guarantees that the value will not be modified. As the value here is the whole object (memory region), in other words, it guarantees that all fields will not be changed.
  • for reference type target – it guarantees that the reference value will not be changed. As the value here is the reference itself (pointing to another object), it guarantees that we will not change it to point to another object. But we can still modify the properties of the referenced object.

Let’s use an example returning a readonly ref:

BookCollection may illustrate the difference between readonly ref in case of both value type and reference type.Continue reading

Among many things that are coming with the upcoming C# 8.0, one perfectly fits the topic of ref structs I’ve raised in my previous postdisposable ref structs.

As one of the blog posts announcing C# 8.0 changes (in Visual Studio 2019 Preview 2) mentions:

“Ref structs were introduced in C# 7.2, and this is not the place to reiterate their usefulness, but in return they come with some severe limitations, such as not being able to implement interfaces. Ref structs can now be disposable without implementing the IDisposable interface, simply by having a Dispose method in them.”

Continue reading

Disclaimer – this article consists of fragments of my book, adapted and re-edited considerably to be presented in the form of an independent whole post.

As already explained in the previous article, managed pointers have their well-justified limitations – especially in that they are not allowed to appear on the Managed Heap (as a field of reference type or just by boxing). However, for some scenarios, it would be really nice to have a type that contains a managed pointer. The main motivation behind such type is Span<T> – which should be able to represent references “inside” objects (interior pointers), stack address or even unmanaged memory.

Ref struct (byref-like type)

Such type should have similar limitations as the managed pointer itself (to not break limitations of the contained managed pointer). Thus, those kinds of types are commonly called byref-like types (as the other name of the managed pointer is simply byref). The most important limitation of such type should be an impossibility to have heap-allocated instances. Thus the direction seems obvious – structs with some additional restrictions should be introduced. Regular structs by default are stack-allocated but may be heap-allocated in various scenarios, like boxing (for example because of casting to an interface).Continue reading

Disclaimer – this article consists of fragments of my book, adapted and re-edited considerably to be presented in the form of an independent whole post.

Most of the time a regular .NET developer uses object references and it is simple enough because this is how a managed world is constructed – objects are referencing each other via object references. An object reference is, in fact, a type-safe pointer (address) that always points to an object MethodTable reference field (it is often said it points at the beginning of an object). Thus, using them may be quite efficient. Having an object reference, we simply have the whole object address. For example, the GC can quickly access its header via constant offset. Addresses of fields are also easily computable due to information stored in MethodTable.

There is, however, another pointer type in CLR – a managed pointer. It could be defined as a more general type of reference, which may point to other locations than just the beginning of an object. ECMA-335 says that a managed pointer can point to:

  • local variable – whether it be a reference to a heap-allocated object or simply stack-allocated type,
  • parameter – like above,
  • field of a compound type – meaning a field of other type (whether it is value or reference type),
  • an element of an array

Despite this flexibility, managed pointers are still types. There is a managed pointer type that points to System.Int32 objects, regardless of their localization, denoted as System.Int32& in CIL. Or SomeNamespace.SomeClass& type pointing to our custom SomeNamespace.SomeClass instances. Strong typing makes them safer than pure,
unmanaged pointers that may be cast back and forth for literally everything. This is also why managed pointers do not offer pointer arithmetic known from raw pointers – it particularly does not make sense to “add” or “subtract” addresses they represent, pointing to various places inside objects or to local variables.

Continue reading

Hi all! I am thrilled to announce that after more than two years of intensive book writing, it is finally available for preorder! Its about 800 pages are solely dedicated to the topic of .NET memory management and its Garbage Collector. With many, many internal workings of all this. I believe, personally, that there is currently no single book or even finite set of articles online that give so comprehensive insight into this topic.


announce

As a person who sincerely loves .NET and related performance topics – and spent quite a lot of time diagnosing various .NET memory-related issues – I’ve just needed to write such book. And as it covers all recent changes in .NET Core 2.1 (including Span, Memory or pipelines), I believe there is no better time to publish such book!

Let me give you an excerpt from the introduction of the book, which should explain my intentions when writing it:

Continue reading