ThisCalculator

Everyday

CentOS High Memory Usage: Causes & Fixes

Updated · Standard formula, shown below

CentOS High Memory Usage: Causes & Fixes

Your CentOS server may show high memory usage because Linux caches files and program data in unused RAM to speed up disk access, and tools like free report this as “used� unless you look at the right columns. To reduce actual memory pressure, you need to identify which processes consume RAM, adjust service limits, and tune kernel parameters like vm.swappiness. This article explains how to interpret memory reports, find the real culprits, and apply practical reductions without breaking your server.

Understanding Linux Memory Reporting

When you run free -h on CentOS, you see a row for “Mem� with columns: total, used, free, shared, buff/cache, and available. The “used� column counts memory used by processes plus memory used for caches. The “available� column estimates how much memory can be reclaimed without swapping. On a healthy server, “used� may be high but “available� is still large because the kernel will drop caches when applications need memory. A common mistake is to look only at “used� and panic, while the system is actually performing well.

To see a clearer picture, use free -h and focus on the “available� column. Also, top or htop shows per-process memory with columns like RES (resident memory) and VIRT (virtual memory). RES is the actual physical RAM a process uses, while VIRT includes shared libraries and mapped files that may not be fully resident. Many administrators mistakenly sum VIRT values and think they have a memory leak, but that number is not a real RAM footprint.

Common Causes of High Memory Usage

Several factors can push memory usage upward:

  • File caching: The kernel caches recently read files (disk buffers) to speed up repeated access. This is normal and can be reclaimed automatically.
  • Web server workers: Apache or Nginx spawn multiple processes or threads, each holding a chunk of memory. PHP-FPM pools can multiply this effect.
  • Database buffers: MySQL/MariaDB and PostgreSQL have buffer pools that intentionally use a large portion of RAM (e.g., InnoDB buffer pool size).
  • Java applications: JVM-based apps allocate a fixed heap size (e.g., -Xmx) that may be larger than needed.
  • Memory leaks: A process slowly grows over time due to a bug, eventually exhausting RAM.
  • Too many services: Running many daemons (mail, DNS, monitoring) each consume a baseline amount of memory.

How to Identify What’s Using Memory

Start with free -h to see overall usage, then use top and press M to sort by memory. For a more detailed view, install htop (yum install htop) and sort by the RES column. To see a snapshot of the top memory consumers, run:

ps aux --sort=-%mem | head -20

This shows process ID, CPU, memory percentage, and command. Pay attention to the %MEM column, which is relative to total RAM. If a single process uses a large percentage, investigate whether it is misconfigured or leaking.

For a historical view, use sar -r (from sysstat package) to see memory trends over time. This helps distinguish a gradual leak from a steady high baseline.

Practical Steps to Reduce Memory Usage

Once you know what is consuming memory, apply these fixes:

  1. Adjust service limits: For Apache, reduce MaxRequestWorkers and KeepAliveTimeout. For PHP-FPM, lower pm.max_children based on average process size. For MySQL, set innodb_buffer_pool_size to 50-70% of available RAM (but not more).
  2. Disable unused services: Use systemctl list-unit-files --state=enabled to see what starts at boot, and disable anything unnecessary with systemctl disable <service>.
  3. Limit Java heap: Set -Xmx to a reasonable value based on your workload, not the default which may be a fraction of physical RAM.
  4. Use zram or swap: If you have swap enabled, the kernel can move idle pages to disk. But swapping too much hurts performance. Consider using zram (compressed RAM swap) for better responsiveness.
  5. Clear caches manually (temporary): sync; echo 3 > /proc/sys/vm/drop_caches will free page cache, but it will repopulate quickly. This is not a long-term fix.
  6. Reboot periodically: For servers with memory leaks that are hard to fix, a scheduled reboot (e.g., weekly) can reclaim leaked memory. This is a stopgap, not a solution.

Kernel Tuning: vm.swappiness and Overcommit

The vm.swappiness parameter controls how aggressively the kernel swaps anonymous pages (process memory) versus page cache. Default is 30 (on a scale of 0-100). Lower values (e.g., 10) make the kernel less likely to swap, which can improve responsiveness for interactive workloads. To change it permanently, edit /etc/sysctl.conf:

vm.swappiness = 10

Then run sysctl -p. Another parameter is vm.overcommit_memory, which controls how the kernel handles memory overcommit. Setting it to 2 (never overcommit) can prevent a single process from reserving more memory than physically available, but it may cause some applications to fail. Use with caution.

When High Memory Is Actually a Problem

High memory usage is only a problem when the system starts swapping heavily or OOM (Out-Of-Memory) killer terminates processes. Signs of trouble include:

  • High values in the “siâ€� and “soâ€� columns of vmstat 1 (swap in/out).
  • Processes being killed with “Killedâ€� in logs (check dmesg for OOM messages).
  • Slow response times even when CPU is idle.

If you see these, you need to reduce memory pressure. But if the “available� column is consistently above 20% of total RAM, your server is likely fine even if “used� is 90%.

Comparing CentOS with Other Distributions

CentOS (and RHEL) uses the same Linux kernel as other distributions, so memory management is similar. However, CentOS 7 and earlier use cgroups v1, while CentOS 8+ uses cgroups v2 (though CentOS 8 is EOL). Some tools like systemd-cgtop can show cgroup memory usage. Compared to Ubuntu, CentOS defaults may have more services enabled (e.g., firewalld, tuned), which can increase baseline memory usage. The tuning principles are the same across distributions, but package names and service names differ.

Frequently Asked Questions

Why does my CentOS server show 90% memory used but only 1GB of processes?

That is almost certainly file cache. The kernel uses free RAM to cache disk data, and it will release it when a process needs memory. Check the “available� column in free -h – if it is high, your server is healthy.

Is it safe to clear the cache with drop_caches?

Yes, it is safe, but it is only a temporary measure. The cache will rebuild as files are accessed, and clearing it can actually slow down disk reads temporarily. Do not use it as a regular maintenance task.

How do I set a memory limit for a systemd service?

Edit the service unit file (e.g., /etc/systemd/system/myservice.service) and add under [Service]: MemoryMax=500M or MemoryLimit=500M (depending on version). Then run systemctl daemon-reload and restart the service.

What is the difference between buffer and cache in free output?

Buffers are used for block device metadata and are relatively small. Cache is the page cache for file contents. Both are reclaimable and not a cause for concern.

Can adding swap reduce memory usage?

Swap allows the kernel to move idle pages to disk, freeing RAM for active processes. It does not reduce the memory footprint of processes, but it can prevent OOM. However, heavy swapping degrades performance, so use it as a safety net, not a primary fix.

Why does my Java app use more memory than the -Xmx setting?

JVM uses memory beyond the heap for metaspace, thread stacks, and native buffers. The heap is only part of the total. Use jcmd <pid> GC.heap_info to see heap usage, and consider setting -XX:MaxMetaspaceSize to limit that too.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.