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!

 

 

prototype07

So…after quite a serious thing which was writing Pro .NET Memory Management book, I’ve decided to experiment with a little pet project for having some more fun. I have quite a few very interesting ideas going on in my head. Yet, I needed to choose one!

And that’s how an idea of OutOfMemory game prototype materialized! Ladies and gentleman, please meet the first in the world card game about .NET-based high performance and memory-aware programming. Sounds so nerdy, doesn’t it?! That’s by design and I like it! From developer to developers, with love 😉 It contains a huge amount of stuff related to programming, hardware architecture and… GC obviously! This is going to be a physical card game, not a computer or a mobile one.

The goal of the game is to build an application. You build it by playing on the table so-called Feature cards – the first player getting a given amount of Feature points wins!

prototype01

But each Feature has its cost! Each Feature card allocates Memory and consumes CPU Ticks. At the end of each player’s turn, you add an appropriate amount of Memory. If you hit a given limit – OutOfMemory occurs! CPU Ticks play also an important role in limiting possible actions in a turn.

In each turn, the player takes a single card from a deck. Or two, if she has an appropriate special card which is… Adam Sitnik‘s card (an example of a Hero card). Another example of .NET Hero card is Ben Adams – very powerful as it both reduces Memory and CPU Ticks, has a special ability (removes all the nasty Issues played against you by your opponents) and even adds a single Feature point (having Ben contributing to your app is a feature by itself)!

prototype02b

Guess who is on the other Hero cards?! Currently, I plan eight such cards!

Card(s) taken from the deck can be used immediately or kept at hand (but there is a limit of cards in hand, reflecting CPU cache my dear!)

There are various other types of cards. For example, there are Garbage Collection Action cards so if you are lucky enough (and plan to keep them in advance) you can clean your Memory periodically.

prototype03

A lot of cards help you to keep Features while reducing their Memory and/or Ticks costs, like Span<T> or Lock-free programming

prototype04

There are also nasty Bug and Issue cards that you can play against your opponents, removing their Feature points or making their app more allocating and slower!

prototype05b

Additionally, there are various Action cards that can be played to receive a short, single-turn benefit. Some influence only you, some a given opponent, and some all the players – like Black Friday cards that makes all Features double-allocating in the next turn (due to high volume traffic!).

prototype06

All this is in a very early prototype stage, requiring possibly quite a lot of rethinking. And a lot of balancing is required to create playable and enjoyable deck. Currently, my prototype consists of 80 cards.

prototype07

I am playing this game a lot with… myself, to balance the very first prototype. When ready, I plan to publish self-printable very rough version and I hope there will be .NET developers out there willing to try it out! With your feedback, we may create an amazing game!

Nevertheless, I would LOVE to start receiving your feedback RIGHT away! Do you like this idea? Do you have ideas of Hero, Bug, Issue, Fix and Feature cards?


If you are want to be informed about further work and the prototype, feel invited to subscribe at a dedicated page!


Note also that this initiative is a part of a bigger Dotnetos initiative – although currently only I am involved in the design of this game, most probably sooner or later all three Dotnetos will be somehow involved in it – I hope so!

Note. All graphics on cards and the cards itself are prototypes and do not reflect the final quality. Moreover, all cliparts were taken from Free Vectors via vecteezy.com.

gcbook

It’s been about half a year since my book has been published and people started to read it. Some even already finished! I thought it would be nice to gather all the reviews I’ve seen so far. There are not so many still – I was able to find 13 reviews on various sites. Still, big thank you for those who write them!

I must admit, I am very, very pleased with those opinions! There are almost no negatives! The greatest satisfaction is given by statements that someone felt a better programmer after reading it. Or applied it in practice immediately. Some reviews are quite comprehensive, some are pretty short. To help you in skimming all them, I’ve highlighted the most interesting (and positive!) parts of them. Negative parts are also highlighted – luckily there is so few of them!


review05 review11


 

Obviously, general statements about the book being very well-written or structured are also very pleasing! Hearing “amazing” about your work is awesome!

 


review10

review04


 

One of the nicest things is to hear that this book is a “must read” for every .NET developer!

 


review09


 

The same about hearing that it is “one of the best books about .NET” or the best book about this topic!

 


review08

review07

review12


 

And even two of those reviews are written by friends of mine, I know them well enough to be sure they are writing sincerely. If they did not like something, they’d write it honestly!

So after more than two years of writing, this is a kind of reward for me to read all this!

 


review02

review03


 

The very first review was kind of problematic because of Amazon’s formatting issue. Not my fault, unfortunately. But luckily reviewer revised his review after correspondence with the Amazon (AFAIK).

 


review06


 

So in summary – I am very pleased to hear that people like the approach taken by me in designing this book. I wanted it to be both very theoretical (a lot of deep-inside stuff and its theoretical basis) and very practical (presented Scenarios and Rules). And it seems it works!

 


 

review13

review01


 

Reviews presented here were taken from the following pages:

If you see another review elsewhere, or you’ve written one, please leave a comment!

And if you’ve read my book already, please write a review somewhere!

 

TL;DR – would be post-mortem finalization available thanks to phantom references useful in .NET? What is your opinion, especially based on your experience with the finalization of your use cases? Please, share your insights in comments!

Both JVM and CLR has the concept of finalizers which is a way of implicit (non-deterministic) cleanup – at some point after an object is recognized as no longer reachable (and thus, may be garbage collected) we may take an action specified by the finalizer – a special, dedicated method (i.e. Finalize in C#, finalize in Java). This is mostly used for the purpose of cleaning/releasing non-managed resources held by the object to be reclaimed (like OS-limited, and thus valuable, file or socket handles).

However, such form of finalization has its caveats (elaborated in detail below). That’s why in Java 9 finalize() method (and thus, finalization in general) has been deprecated, which is nicely explained in the documentation:

“Deprecated. The finalization mechanism is inherently problematic. Finalization can lead to performance issues, deadlocks, and hangs. Errors in finalizers can lead to resource leaks; there is no way to cancel finalization if it is no longer necessary; and no order is specified among calls to finalize methods of different objects. Furthermore, there are no guarantees regarding the timing of finalization. The finalize method might be called on a finalizable object only after an indefinite delay, if at all.”

Continue reading

As a part of my consultancy job, I have a pleasure to help various customers with problems that could be described collectively as GC-related (or memory-related in general). One day Tamir Dresher from Clarizen company (BTW, an author of Rx.NET in Action) contacted me with such an extremely interesting message (emphasis mine):

We are experiencing a phenomenon of GC duration of 15 minutes in our backend servers. (…) Do you think we can have a session with you and perhaps you’ll have ideas on how to find the root cause?

15 minutes! That’s an infinity! If we see something like this, one thought comes to mind – something really serious must be happening there! As nowadays most of such problems may be diagnosed remotely, after signing NDAs we could go straight into attacking the problem. Clarizen has provided a very well-prepared and concise summary of their architecture and current findings.Continue reading

zerogclead

A few months ago I wrote an article about Zero GC in .NET Core 2.0. This proof of concept was based on a preview version of .NET Core 2.0 in which a possibility to plug in custom garbage collector has been added. Such “standalone GC”, as it was named, required custom CoreCLR compilation because it was not enabled by default. Quite a lot of other tweaks were necessary to make this working – especially including required headers from CoreCLR code was very cumbersome.

However upcoming .NET Core 2.1 contains many improvements in that field so I’ve decided to write follow up post. I’ve also answered one of the questions bothering me for a long time (well, at least started answering…) – how would real usage of Zero GC like in the context of ASP.NET Core application?

.NET Core 2.1 changes

Here is a short summary of most important changes. I’ve updated CoreCLR.Zero repository to reflect them.

  • first of all, as previously mentioned, now standalone GC is pluggable by default so no custom CoreCLR is required. We will be able to plug our custom GC just by setting a single environment variable:
  • as standalone GC matured, documentation in CoreCLR appeared
  • a great improvement is that code between library implementing standalone GC and CoreCLR has been greatly decoupled. Now it is possible to include only a few files directly from CoreCLR code to have things compiled:

    Previously I had to create my own headers with some of the declarations from CoreCLR copy-pasted which was obviously not maintanable and cumbersome.
  • loading path has been refactored slightly. InitializeGarbageCollector inside CoreCLR calls GCHeapUtilities::LoadAndInitialize() with the following code inside:

    Inside LoadAndInitializeGC there is a brand new functionality – verification of GC/EE interface version match. It checks whether version used by standalone GC library (returned by GC_VersionInfo function) matches the runtime version – major version must match and minor version must be equal or higher. Additionaly, GC initialization function has been renamed to GC_Initialize.
  • core logic of my the poor man’s allocator remained the same so please refer to the original article for details

ASP.NET Core 2.1 integration

As this CoreCLR feature has matured, I’ve decided do use standard .NET CLI instead of CoreRun.exe. This allowed me to easily test the question bothering me for a long time – how even the simplest ASP.NET Core application will consume memory without garbage collection? .NET Core 2.1 is still in preview so I’ve just used Latest Daily Build of .NET CLI to create WebApi project:

I’ve modified Controller a little to do something more dynamic that just returning two string literals:

Additionally, I’ve disabled Server GC which is enabled by default. Obviously setting GC mode does not make sense as there is no GC at all, right? However, Server GC crashes runtime because GC JIT_WriteBarrier_SVR64 is being used which requires valid card table address – and there are no card tables either 🙂

Then we simply compile and run, remembering about the environment variable:

Everything should be running fine so… congratulations! We’ve just run ASP.NET Core application on .NET Core with standalone GC plugged in which is doing nothing but allocating.

Benchmarks

I’ve created the same WebApi via regular .NET Core 2.0 CLI for reference. Then via SuperBenchmarker I’ve started simple load test: 10 concurrent users making 100 000 requests in total with 10 ms delay between each request.

.NET Core 2.1 with Zero GC:

zerogcaspnetcore02

.NET Core 2.0:

zerogcaspnetcore03

As we can see classic GC from .NET Core was able to process slightly more requests (357.8 requests/second) comparing to version with Zero GC plugged in. It does not surprise me at all because my version uses the most primitive allocation based on calloc. I’m quite surprised that Zero GC is doing so well after all. However, this is not so interesting because I assume that replacing calloc with a simple bump a pointer allocation would improve performance noticeably.

What is interesting is the memory usage over time. As you can see in the chart below, after a minute of such test, the process using Zero GC takes around 1 GB of memory. This is… quite a lot. Not sure yet how to interpret this. Version with regular GC ended with a stable 120 MB size. Both started from fresh run.

zerogcaspnetcore

This would mean that each REST WebApi requests triggers around 55 kB of allocations. Any comments will be appreciated here…

Update 30.01.2018: After debugging allocations during single ASP.NET requests, most of them comes from RouterMiddleware. This is no surprise as currently this application does almost nothing but routing… I’ve uploaded sample log of such single request which seems to be minimal (others are allocating some buffers from time to time). It consumes around 7 kB of memory.

We can often hear that allocation of objects is “cheap” in .NET. I fully support this sentence because the most important part is its continuation – allocation is cheap but allocating a lot of objects will hit you back as sooner or later garbage collector will kick in and start messing around. Thus, the fewer allocations, the better.

However, I would like to add a few words about “allocation is cheap” itself. This is true to some extent because the typical path of objects allocation is indeed really fast. So-called bump a pointer technique is most often used. It consists of the following simple steps:

  • it uses so-called allocation pointer as an address of a newly created object
  • it increases allocation pointer by the requested size (so next object will be created there

Continue reading

Zero Garbage Collector on .NET Core

Starting from .NET Core 2.0 coupling between Garbage Collector and the Execution Engine itself have been loosened. Prior to this version, the Garbage Collector code was pretty much tangled with the rest of the CoreCLR code. However, Local GC initiative in version 2.0 is already mature enough to start using it. The purpose of the exercise we are going to do is to prepare Zero Garbage Collector that replaces the default one.

Zero Garbage Collector is the simplest possible implementation that in fact does almost nothing. It only allows you to allocate objects, because this is obviously required by the Execution Engine. Created objects are never automatically deleted and theoretically, no longer needed memory is never reclaimed. Why one would be interested in such a simple GC implementation? There are at least two reasons:Continue reading

Trace Compass

.NET Core on Linux is still very fresh in 2017. First production deployments are just beginning to emerge. Consequently, development on this platform is only beginning to show up. There is a lack of knowledge and good practices related to virtually every aspect of the existence of this environment. One of them is monitoring and diagnostic aspect. How can we monitor and analyze the health of our application?

The easiest way of getting tracing data is by using official perfcollect bash script and then using Perfview on Windows to analyze this recorded data. This approach has some drawbacks. The main one is are fairly limited analysis results available in PerfView. The second, less burdensome, is the need for Windows to… analyze Linux data. Recently Sasha Goldstein has created a lot of valuable material on this subject and I invite you to review the list posted at the end of this post.

I would like to present another diagnostic option here. This is using the free Eclipse Trace Compass tool. Continue reading

Book Cover

 

I don’t know if you have a driving license. Even if not, you will surely understand this sublime analogy presented by me. Sometimes, you drive a car and know traffic regulations. You can drive this manner successfully for the whole life. However, if you aim to be a professional driver, an old stager, it takes whole days in a car and sooner or later you get dirty with grease by working with an engine. This is how I see the .NET developer’s life. The vast majority may ride „very well”, knowing the syntax, design patterns, tricks of trade. They are professionals. Yet, there is a small group of geeks, nerds, old stagers, that are looking for something more. They want to understand CLR internals, know how does everything work, how to dig in into memory and how to use raw tools such as WinDbg. I consider this is plainly speaking a mind-absorbing occupation and can draws everybody’s attention, even for a while. The popularity of devWorkshops delivered in Poland  by me and Sebastian Solnica confirms this presumption.Continue reading