If you've been checking your Minecraft Server statistics, you may have noticed that your memory has jumped all the way up to 100%. This is a normal occurrence for Java applications and does not indicate a problem. In this post, we will explain why this is and how to know if you really need more RAM.

Unused memory is wasted memory. Java is a garbage-collected language, which means it only cleans up unused memory when it runs out. This process can take a long time and requires your server to lock up temporarily. Therefore, Java likes to run this process as infrequently as possible to reduce the frequency of these lag spikes. As a result, you may see high memory usage for your server, even though your server's memory usage is not actually so high.

How do I know if I need more RAM?

The best way to check your memory usage is to install the Spark plugin. This is a commonly used plugin that helps you to check the performance of your server and find causes for lag. In this case, we'll be using it to determine if your server actually needs more memory. There are several things that can indicate that your server is running out of memory and needs more.

After Spark is installed on your server, run the command /spark healthreport --memory. This command will display a number of statistics. The number you're primarily interested in is G1 Old Gen pool usage.  This number will show how much memory your server is choosing to retain long-term. You should aim to keep this number below 75% of the limit. If your server is using more than 75% of the limit under the G1 Old Gen pool usage field, then you may want to consider upgrading your server, or looking into the possibility of a memory leak.

The second indicator that you can use to determine if your server is running out of memory is by looking at garbage collector activity in your server. To do this, run the command /spark gc. This will display two sections, and the one we're interested in is the G1 Old Generation collector section. In an ideal scenario, you should have 0 total collections. If you have 0 total collections, then your server is not in need of more RAM. Otherwise, you should check the average frequency of collections. If this number is any less than an hour or so, then it may be an indication that your server needs more memory. It could also be indicative of a memory leak.

What is a memory leak?

A memory leak happens when a Java application uses memory without freeing it. This can happen for a number of reasons, but is most commonly caused by poorly written or buggy plugins. If you experience abnormally high memory usage, then you may have a plugin that's leaking memory. The easiest way to diagnose this is to remove plugins until the problem goes away. This can often take quite some time though.

If you are technically inclined, there is a more scientific way to find memory leaks. Firstly, you're going to want to take a heap dump. This can be done by running /spark heapdump --compress xz. This will dump all memory your server is using and compress it (so the file size isn't massive). Note: This will create a large lag spike on your server. Once the heap dump is finished, you can download the heap dump from your server and analyse it with a number of tools. Some popular tools are HeapHero (free), Eclipse MAT (free), JXray (paid with free trial), and Yourkit (paid). Do not share your heap dump with people that you do not trust. Heap Dumps will contain sensitive information including private database credentials and player IP addresses.

Once you've opened your heap dump with one of these tools, you should search for plugins that are using high memory. There is a good chance that these plugins are leaking memory. You are encouraged to share this information with the plugin developer, as they may be able to assist you with the problem or fix the bug. If most of your memory is held by the server (specifically in chunk-related objects), this indicates that your server is just running out of memory due to too many chunks being loaded, and you may need to upgrade to more memory.

What is Garbage Collection anyways?

Garbage collection is the process Java uses to manage RAM. When your server needs memory to load a chunk or store information about a player, it requests this memory from Java. When your server is done with the memory it's used (for example, when a player quits or a chunk is unloaded), Java does not immediately free that memory up. Instead, it considers this memory "garbage": memory that isn't being used but hasn't been freed up. Periodically, Java will run a process to find all of this garbage memory and free it up. This process is called Garbage Collection.

There are a number of different methods that are used for garbage collection in Java. The most popular one used for Minecraft servers is called G1GC, which stands for Garbage-First Garbage Collector. This garbage collector splits up memory into two groups: memory that was recently allocated and is more likely to be garbage, and memory that was allocated a long time ago and has been proven to not be garbage in the past. It also has two different types of cycles that run. The first is a Young Gen cycle, which only scans the recently allocated memory. The second type is an Old Gen cycle, which scans all of the memory, including memory that was allocated a long time ago. By searching through memory that was recently allocated, G1GC is more likely to find memory to free quickly. These searches are very fast, typically on the order of double digit milliseconds. Therefore, G1GC prefers to only use Young Gen cycles where possible. This results in small, and hopefully infrequent, pause times.

Sometimes, a Java process has been running for a long time and has accumulated a lot of memory in the Old Gen pool (that is, memory that has been allocated for a long time and hasn't yet been freed). If Java can't free enough memory with a Young Gen cycle, it will proceed to an Old Gen cycle, to scan this long-term Old Gen pool searching for memory that can be freed. This process has a very long pause time that could reach into the single digit seconds. This causes a very jarring lag spike on your server that could last several seconds long. These cycles should be very rare, and ideally shouldn't run at all. If they are running frequently, then it is an indication that your server needs more memory, as it is actually using all of the RAM that it has access to use.

So how much memory does my server actually need?

Well, that's a tough question to answer, and it depends on a lot of factors. For the most part, it's going to depend on how many chunks you have loaded. This is decided by three main factors: the number of players you have online, your server's view distance, and how spread out your players are. The more chunks your server has loaded at any one time, the more memory your server is going to need. Large view distances are the primary cause of servers running out of memory. To fix this, you'll need to lower your view distance in server.properties and your no-tick view distance in paper.yml. Even decreasing these values by 1 can have a massive impact on the number of chunks your server is loading. To know how many chunks your server is loading, you can use the command /paper chunkinfo. At the bottom of the output, you'll see Chunks in all listed worlds, and the number after Total indicates how many chunks your server has loaded.

Some plugins will also increase your server's memory usage. The biggest culprits of this are web-map plugins like Dynmap, Pl3xMap, and BlueMap. These plugins will use large amounts of extra memory while rendering their maps, and can cause memory problems. If you are using these plugins and have memory issues, then these plugins may be the cause. Consult the documentation of these plugins to learn how to decrease their memory usage, or upgrade your available memory if you have problems when using these plugins.

Does world count matter?

While having more worlds can result in more chunks being loaded, it is not going to have a massive impact on your server's memory usage. Memory is primarily used by chunks, and while extra worlds do load spawn chunks by default, this is only a relatively small number. Only a few extra worlds will not have a significant impact on the amount of memory your server uses. Always use the /paper chunkinfo command to determine how many chunks you have loaded.

Will more RAM improve my performance?

Maybe. If you have a lot of Old-Gen garbage collection activity, then you will probably benefit from additional RAM. If you don't have any Old-Gen garbage collection activity, and your server isn't running out of memory, then adding more memory won't improve your performance. In fact, giving Java too much memory may be detremental to your server's performance, as more memory makes the garbage collector work harder, causing your server to lag more. You may find different recommendations depending on who you ask, but we don't recommend allocating more than 16-20GB of memory to your server. If you are having server performance issues, you will likely get more benefit out of upgrading your CPU. Most performance issues are caused by poor, outdated CPUs rather than low amounts of memory.