Dev Diary #4 (Part 2 of 3) – September-October 2018

Part 2 – Memory Leaks

We posted the first part about “Uninitialized Variables” on Monday October 1st 2018. This is the second part: “Memory Leaks”.”

This diary concerns itself with fairly ‘low level’ topics, but we will try to explain everything so that non-programmers can also follow and get a good idea about what’s going on.
For the programmers among you – we are simplifying a lot here, so please bear with us. The Guild 3 is written in C++, so please put on your C++-tinted glasses while reading this.

The Issue

“Leaking memory” sounds very unpleasant, and it truly is a nasty problem. To understand this (and the next) issue, we first should quickly discuss how memory is used by our game, and indeed pretty much any program. To do this, I’ll employ a little analogy:

Imagine your PC is a library. The hard disks and other permanent storage are the shelves of books along the walls and in the library vaults, where knowledge and data is stored for long durations. Every running program is a visitor to this library. To actually do anything with all the information, the programs first have to retrieve it from long term storage and get it into their personal ‘work space’, one or more reading tables that are used for interacting with the information. This is essentially the purpose that your computer’s main memory serves.

Some programs might require only very little information, so they only need a tiny slice of memory (a small table somewhere in the corner, in our library analogy). Others operate on huge amounts of data at once and therefore their workspace spans several desks or even desks in multiple rooms, all littered with open books and loose pages.

Of course, as a good citizen, whenever you are done with working on a book retrieved from storage, you should return it. Not only so that someone else can work on it, but also so that you don’t keep eating up more and more space in the library, filling desk after desk with books that you don’t need anymore.

The Effect

This is, however, exactly what happens if someone talks about a ‘memory leak’. A program has to request memory from the operating system before it can use that memory for storing data – data like textures, meshes, program code, script files, sounds, and whatever else needs to be worked on. The operating system happily fulfils those requests, but it also expects the program to return memory that is no longer used. If this doesn’t happen, then the memory usage will continuously swell up.

Nowadays, thanks to virtual memory and 64 bit operating systems, it is quite difficult to actually run out of memory. You have to do some pretty outrageous things before the operating system will actively deny more memory for a program. What happens instead is that performance will degrade over time, while memory usage slowly grows to epic proportions. Before long, the program will become essentially unusable, and the user will kill it.

The Solution

Writing modern code in C++ makes it fairly easy to avoid memory leaks. The straight “I forgot to return memory to the operating system” case I mentioned above is usually not what happens. What happens more frequently is that ‘stale’ data is kept in memory. No one really needs this data anymore, but someone somewhere is ‘keeping it alive’.

These issues are very annoying and time consuming to fix. There aren’t really any tools or automated helper programs we can use. Rather, we have to make sure to always do diligent bookkeeping, keeping only the data around that is really needed, and properly freeing unused memory so it can go back into the operating system.

If you are interested to find out more about the issue of memory leaks, this Wikipedia article is a good location to get started:

We will soon continue this dev diary story with “Memory Fragmentation”. Stay tuned.