Modern computers have loads of memory. But it's very easy to burn through it all in seconds if your code is not efficient about allocating and using memory.
Did you know that one simple mistake can make your code allocate 1600 times more memory than absolutely necessary?
Don't be 'that developer' who keeps crashing the development server with an OutOfMemory exception.
And you certainly don't want to be responsible for inflating the hardware budget. Can you imagine having to explain to your team that 512 GB of memory is not enough to run your code on the production server?
Let me help you.
Modern computers have loads of memory. But it's very easy to burn through it all in seconds if your code is not efficient about allocating and using memory.
Did you know that one simple mistake can make your code allocate 1600 times more memory than absolutely necessary?
Don't be 'that developer' who keeps crashing the development server with an OutOfMemory exception.
And you certainly don't want to be responsible for inflating the hardware budget. Can you imagine having to explain to your team that 512 GB of memory is not enough to run your code on the production server?
Let me help you.
It doesn't have to be like this. If you have a good understanding of the garbage collection process and follow a few simple best practices, you can dramatically reduce the memory footprint of your code.
Sound good?
In the last 10 years I have learned the secrets of garbage collection in .NET, and in this course I am going to share them all with you.
In a series of short lectures I will take a detailed look at the garbage collection process. I will show you all of the memory allocation problems you can expect when writing C# code, like unexpected boxing, string duplication, collection resizing, and more. I'll teach you quick and easy strategies to resolve these problems.
By the end of this course you will be able to master the garbage collector.
Why should you take this course?
You should take this course if you are a beginner or intermediate C# developer and want to take your skills to the next level. Garbage collection and memory management might sound complicated, but all of my lectures are very easy to follow and I explain all topics with clear code and many instructive diagrams. You'll have no trouble following along.
Or maybe you're working on a critical section of code in a C# project, and need to make sure your memory usage is as efficient as possible? The tips and tricks in this course will help you immensely.
Or maybe you're preparing for a C# related job interview? This course will give you an excellent foundation to answer any questions they might throw at you.
In this lecture I explain how this course is organised and I describe each of the upcoming sections in detail.
In this lecture I will tell a bit more about myself, my career, and my motivation to become an online trainer.
In this lecture we're going to look at the theory behind .NET memory management. What exactly is Garbage Collection, and how does it work?
Many lectures in this course contain source code examples. Feel free to download the code and follow along. And here's the good news: it doesn't matter if you have a Window, Mac or Linux computer. The code will run on all three operating systems.
In this lecture I demonstrate how my solutions and projects run on all operating systems. I will show you how to build and run the source code on a Mac, on Linux and in Visual Studio running on Windows 8.
At the end of this lecture you will have learned that .NET code is portable and can run on at least five different operating systems.
Welcome to the Fundamentals of .NET Memory Management section. I will give a quick introduction on how the section is organised before we get started.
This lesson will lay down some groundwork and explain in detail what the stack is for, and how data on the stack is laid out in memory.
After completing this lecture you will have learned which data is stored on the stack and what happens when this data goes out of scope. Finally, you will have seen a Stack Overflow exception, and know how to avoid this exception in your own code.
This lesson will lay down some groundwork and explain in detail what the heap is for, and how data on the heap is laid out in memory.
After completing this lecture you will have learned which data is stored on the heap and what happens when variables that refer to this data go out of scope. Finally, you will be able to explain what the 'Garbage collection' process does.
A popular question that often comes up in job interviews is: "what is the difference between a value type and a reference type?"
This lecture looks at value types in detail. What are value types, how do they store their data, and what happens when value types are assigned or compared? After completing this lecture you will be able to answer all of these questions with ease.
A popular question that often comes up in job interviews is: "what is the difference between a value type and a reference type?"
This lecture looks at reference types in detail. What are reference types, how do they store their data, and what happens when reference types are assigned or compared? After completing this lecture you will be able to answer all of these questions with ease.
Value types and reference types are both derived from the same common base class "Object". This is a nice feature of the .NET Framework, but behind the scenes it creates some problems for the runtime environment because reference types can never exist on the stack.
In this lecture you will learn how .NET uses a cool trick called "Boxing" to get around this problem. After completing the lecture you will be able to explain what boxing and unboxing is, and why it is neccesary.
Congratulations on finishing this section. This is a recap of what we have learned.
Welcome to the Detailed Look At Garbage Collection section. I will give a quick introduction on how the section is organised before we get started.
The .NET Garbage Collector is responsible for cleaning up all dereferenced objects on the heap. In this lecture we are going to take a long hard look at its internal architecture.
I will show you how the Garbage Collector uses a mark-and-sweep cycle to periodically clean the heap, how it uses generations to sort objects into short-living and long-living groups, and how it is specifically optimized for handling large objects.
After completing this lecture you will be able to describe in detail how the Garbage Collector works. You will also be aware of the assumptions it makes about object sizes and lifetimes.
In this lecture we're going to look at a couple of specific performance improvements you can make to your code, that will help you work with the Garbage Collector instead of against it.
We will look in detail at the assumptions the Garbage Collector makes about the size and lifetime of the objects in your code, and how you can take advantage of these assumptions by carefully designing your objects.
After completing this lecture you will have learned how to write fast and efficient code that works in harmony with the Garbage Collector.
In this lecture we are going to take a closer look at finalisers, which are special methods that are called by the .NET Garbage Collector just before an object gets deallocated. Finalisers offer a very convenient safety net for last-minute deallocation and disposing of resources held by the object.
But finalisers are dangerous and very hard to get right. I will show you three big disadvantages of finalisers in terms of code robustness and memory performance.
Sometimes an object needs to access scarce operating system resources, like a graphics device handle, a database connection, or a block of unmanaged memory. The Dispose pattern is an efficient design pattern in .NET to quickly release these resources when they are no longer needed.
In his lecture you will learn why the dispose pattern is much more efficient than simply releasing the resources in the finaliser, and I will also teach you how to write a reference implementation of the design pattern.
Congratulations on finishing this section. This is a recap of what we have learned.
Welcome to the Simple Tricks section. I will give a quick introduction on how the section is organised before we get started.
The .NET runtime uses a very cool trick called 'boxing' that allows you to use value types and reference types interchangeably in your code.
In this lecture I will use a test program to measure exact how much overhead the boxing operation introduces. You will see how to use the log profiler built into the Mono framework to track what the garbage collector is doing while the program is running.
After completing this lecture you will have learned why boxing is best avoided in mission-critical code.
Strings in .NET are immutable. This can introduce a large memory footprint when modifying strings, especially when done in a loop.
In this lecture I'll show you a test program that builds a string of 10,000 characters using either simple string concatenation, or the StringBuilder class. We will investigate exactly how much heap memory is allocated, how often the garbage collector runs, and which methods are called in each scenario.
By the end of the lecture you will have learned why you should always use a StringBuilder to modify strings in mission critical code.
Structs in C# are Value Types, which means they are allocated inline with other data, either on the stack or on the heap. This can save a lot of memory, especially if you quickly need to allocate millions of items.
In this lecture I will show you a test program that uses structs and classes to store a large amount of data. The struct- and class-based implementations will go head to head to determine which has the smallest memory footprint.
By the end of the lecture you will have learned in which scenarios a struct is the best choice for storing data.
Collections and lists in .NET automatically resize their internal buffer to accommodate the addition of new items. This is a very nice feature because it means you never have to worry about the size of your lists.
But successive resizes can litter the heap with dereferenced storage buffers and inflate the memory footprint of your code. I will demonstrate a program that fills a list with items and ends up allocating much more memory than it actually needs.
By the end of this lecture you will have learned a very simple trick to keep the memory allocation of lists and collections firmly under control.
LINQ is a nice feature of the C# language that lets you access enumerated data with a flexible and powerful query language. LINQ queries can access any data that supports the IEnumerable interface. But thoughtless use of LINQ can produce a large memory overhead and can significantly slow down your code.
In this lecture I will show you a spellchecker that uses LINQ and allocates way too much memory. Then I'll demonstrate a simple change that has a dramatic impact on the memory footprint.
In this lecture I would like to thank you for finishing the course and offer some final words.
OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.
Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.
Find this site helpful? Tell a friend about us.
We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.
Your purchases help us maintain our catalog and keep our servers humming without ads.
Thank you for supporting OpenCourser.