[LNMP]Memory Optimization

Problem Description

Recently, my server ran into an issue where it would frequently kill my Tomcat process when memory ran low. Since the overall traffic isn’t very high, LNMP and Tomcat are currently running on the same machine, but this caused Tomcat-related Java applications to become unavailable.

1
free -m

Checking the memory usage, I found the operating system had only about 60MB of memory left – almost completely used up. This situation persisted for about a month, and it was a constant source of frustration. I considered adding more memory but thought it was too expensive. When resources are insufficient, there are generally two approaches: the first is to add resources, and the second is to optimize existing resources. For someone on a budget like me, the second approach is usually my first choice.

Initially, I thought Tomcat itself or some other process was consuming too much memory. After running:

1
top

I found that php-fpm processes were often the ones consuming the most memory.

To view the top 40 memory-consuming processes:

1
ps auxw | head -1; ps auxw | sort -rn -k4 | head -40

I found that php-fpm dominated the top 40 processes, with memory usage ranging from 2% to 7%. The problem was now quite clear – the culprit was php-fpm.

Solution

You can control the number of php-fpm child processes by configuring the pm.max_children property. First, open the php-fpm configuration file:

1
vim /etc/php-fpm.d/www.conf

pm.max_children defaults to 50. Each process uses 1%-2.5% of memory, which adds up to consuming most of the memory. Try reducing the value – I set mine to 25 (also referencing other blogs). At the same time, check the following two properties:

  • pm.max_spare_servers : This value represents the maximum number of idle processes. If idle processes exceed this value, they will be cleaned up.
  • pm.min_spare_servers : The minimum number of idle processes. If idle processes fall below this value, new child processes are created.

Neither of these values should exceed the pm.max_children value. Typically, pm.max_spare_servers is set to 60%-80% of the pm.max_children value.

Finally, restart php-fpm:

1
service php-fpm restart

Check the memory again:

1
free -m

I found there was about 600MB of free memory remaining. Even after starting Tomcat, there was still about 300MB to spare.

Reference: https://www.jb51.net/article/129528.htm

1
2

Hope this helps! If you need anything else, feel free to let me know.