I am trying to run a long-running command in docker and I am seeing increasing memory consumption during the command execution.
I am running a test suite composed of 741 tests and 3390 assertions with PHPUnit in the context of a Laravel application. Most of those tests are integration tests which use a database connexion, redis and s3 services in docker-compose. I am producing a code coverage report with this test run. Here is the exact command I run
docker-compose run phpunit --verbose --testdox --colors=never --stop-on-error --stop-on-failure --coverage-clover coverage.xml
I have tried many ways to see where the memory was leaked (is it Docker, PHP or PHPUnit?). Here are the memory reports I set up with their results:
- PHPUnit by defaults reports his memory usage at the end of the run. -> It was always around 80-100MB which is fine.
- I used the
teardown
function and printed thememory_get_peak_usage
. -> It was very similar to the previous something along 80-100 and it increased very slightly to 120MB in the later test. Seems fine - I added
passthru('ps -o pid,user,%mem,command ax | sort -b -k3 -r | head')
in theteardown
function. -> I could see my memory consumption rise at very fast rate. I figured it matched the same percentage as line #4, thus inferring it was close to 6.5G by the end of the run. The only process using RAM wasphpunit
. - From my host, I would run
docker stats --format "table {{.Name}}\t{{.MemPerc}} - {{.MemUsage}}\t{{.BlockIO}}"
-> Same thing, memory increasing to 6.5 GB of RAM by the end of the run. The only container having increasing memory usage was the one running phpunit. Other containers from docker-compose didn't move (database, redis, s3, etc). - From my host, I would run
watch -n 1 free -m
to report RAM usage on my whole computer -> Same thing, memory increasing to 6.5 GB of RAM by the end of the run. As soon as the command completed, the 6.5 GB of RAM was instantly released.
My problem is very similar to this one: Docker does not free memory after creating and deleting files with PHP. I have tried the solutions proposed. I ran echo 3 > /proc/sys/vm/drop_caches
and sync && sysctl -w vm.drop_caches=3
in privileged
mode. The memory usage was not different, but I could see that the BlockIO was now increasing at the same rate than the memory usage which it did not do without one of those commands.
UPDATE april 28, 2021:
It ended up not being a problem with Docker but a problem with PHPUnit. When the tests are run with processIsolation=false
PHPUnit seems to be leaking. My understanding is that processIsolation=true
, a new process is launched for every test case. So memory is freed between each tests, but then it takes way more time to execute.
processIsolation=false
: Fast but leaky memory
processIsolation=true
: Slow but leaked memory is release in between tests