Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak caused by meminfo_dump #81

Open
squio opened this issue Sep 19, 2018 · 5 comments
Open

Memory leak caused by meminfo_dump #81

squio opened this issue Sep 19, 2018 · 5 comments
Labels

Comments

@squio
Copy link

squio commented Sep 19, 2018

Looks like meminfo_dump itself causes unreported memory leaks.

Background: I tried to trace back a memory leak to a suspected XMLDom issue by running a method call in a loop, but then noticed that the actual memory usage was caused by meminfo_dump in this specific case.

Isolated test code (part of a big Laravel command, but run in isolation):

    public function dummy()
	{
		
	}
	
	public function MemTest($iterations=1)
	{
		for ($iteration = 1; $iteration <= $iterations; $iteration++)
		{
			$this->dummy();
			// $this->LoadXML(...);
			$gc = gc_collect_cycles();
			printf("MemTest %02d - gc: %d, peak mem: %5.3f MiB\n", 
                             $iteration, $gc, memory_get_peak_usage(false)/1000000);
			meminfo_dump(fopen(sprintf('meminfo-test-%02d.json', $iteration), 'w'));			
		}
	}

This results in the following output:

Memtest - running 100 iterations...

MemTest 01 - gc: 0, peak mem: 13.677 MiB
MemTest 02 - gc: 0, peak mem: 15.172 MiB
MemTest 03 - gc: 0, peak mem: 15.501 MiB
MemTest 04 - gc: 0, peak mem: 15.827 MiB
MemTest 05 - gc: 0, peak mem: 16.153 MiB
MemTest 06 - gc: 0, peak mem: 16.479 MiB
MemTest 07 - gc: 0, peak mem: 16.805 MiB
MemTest 08 - gc: 0, peak mem: 17.131 MiB
^C

So about 330 kB wasted on each iteration.
See below for meminfo output for 1st and last iteration.

After commenting out the line meminfo_dump(...) the following - expected - output is returned:

Memtest - running 99 iterations...

MemTest 01 - gc: 0, peak mem: 13.676 MiB
MemTest 02 - gc: 0, peak mem: 13.676 MiB
MemTest 03 - gc: 0, peak mem: 13.676 MiB
MemTest 04 - gc: 0, peak mem: 13.676 MiB
MemTest 05 - gc: 0, peak mem: 13.676 MiB
MemTest 06 - gc: 0, peak mem: 13.676 MiB
MemTest 07 - gc: 0, peak mem: 13.676 MiB
...
MemTest 96 - gc: 0, peak mem: 13.676 MiB
MemTest 97 - gc: 0, peak mem: 13.676 MiB
MemTest 98 - gc: 0, peak mem: 13.676 MiB
MemTest 99 - gc: 0, peak mem: 13.676 MiB

Inspection of the meminfo dumps shows the same trend for overall memory usage but does not show any detail of where the memory went; this is consistent with the documentation which states that memory in extensions is not shown.

NOTE: this is based on a legacy version of PHP 7.0.30 which we need for an existing Laravel 5.5 based project; meminfo was built from source from the master branch today.

PHP 7.0.30 (cli) (built: May  9 2018 06:56:41) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans

meminfo summary, first iteration:

{
  "header" : {
    "memory_usage" : 13613016,
    "memory_usage_real" : 14680064,
    "peak_memory_usage" : 13677144,
    "peak_memory_usage_real" : 14680064
  },
Type Instances Count Cumulated Self Size (bytes)
string 6720 629831
array 1843 132696
boolean 1185 18960
null 1076 17216
integer 497 7952
Closure 231 16632
Symfony\Component\Console\Input\InputOption 112 8064
Symfony\Component\Console\Input\InputDefinition 83 5976
Illuminate\Routing\Route 68 4896
Symfony\Component\Console\Input\InputArgument 36 2592
unknown 15 240
Symfony\Component\Console\Formatter\OutputFormatterStyle 5 360

meminfo summary, final iteration:

{
  "header" : {
    "memory_usage" : 46240416,
    "memory_usage_real" : 48234496,
    "peak_memory_usage" : 47126928,
    "peak_memory_usage_real" : 48234496
  },
Type Instances Count Cumulated Self Size (bytes)
string 6703 629389
array 1821 131112
boolean 1185 18960
null 1076 17216
integer 497 7952
Closure 231 16632
Symfony\Component\Console\Input\InputOption 112 8064
Symfony\Component\Console\Input\InputDefinition 83 5976
Illuminate\Routing\Route 68 4896
Symfony\Component\Console\Input\InputArgument 36 2592
unknown 15 240
Symfony\Component\Console\Formatter\OutputFormatterStyle 5 360
@BitOne
Copy link
Owner

BitOne commented Oct 26, 2018

Thanks @squio for this report,

We have some tests to make sure we don't leak: https://github.com/BitOne/php-meminfo/blob/master/extension/php7/tests/dump-memory_leak.phpt

But it seems it's not sufficient enough.

Do you have the same problem on a more recent version of PHP? Can you try without xdebug enabled? And finally, do you have any code that you can provide so I can do some testing?

Thank you very much!

@BitOne BitOne added the bug label Oct 26, 2018
@jc21
Copy link

jc21 commented Dec 10, 2018

Hi there, speaking of that test (tests/dump-memory_leak.phpt), compiling fails that particular test for me on some builds and passes on others, consistently.

  • EL6 PHP 7.0: PASS
  • EL6 PHP 7.1: FAIL
  • EL6 PHP 7.2: FAIL
  • EL6 PHP 7.3: PASS
  • EL7 PHP 7.0: PASS
  • EL7 PHP 7.1: PASS
  • EL7 PHP 7.2: PASS
  • EL7 PHP 7.3: FAIL

An example fail output from EL6 PHP 7.2:

=====================================================================
TEST RESULT SUMMARY
---------------------------------------------------------------------
Exts skipped    :    0
Exts tested     :   15
---------------------------------------------------------------------

Number of tests :   12                 1
Tests skipped   :   11 ( 91.7%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :    1 (  8.3%) (100.0%)
Expected fail   :    0 (  0.0%) (  0.0%)
Tests passed    :    0 (  0.0%) (  0.0%)
---------------------------------------------------------------------
Time taken      :    2 seconds
=====================================================================

=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
meminfo_dump check there's no memory leak [tests/dump-memory_leak.phpt]
=====================================================================

edit: added php 7.3 to results

@GusAntoniassi
Copy link

@jc21 I am having the same problem on CentOS 6.9 running PHP 7.1.11. Tried it on a Docker container based on php:7.1-apache based on Debian 8 and it works, all tests passing. I will try to run some more tests to see if it is CentOS specific.

I was already having this issue from my PHP routines, which led me to try out this repo. The exact same amount of memory is leaking in the test (2097152 bytes), so I am thinking this might be something OS or PHP specific.

@jc21
Copy link

jc21 commented Dec 12, 2018

I've implemented the builds on a different hardware and now I'm getting different results:

  • EL6 PHP 7.0: PASS
  • EL6 PHP 7.1: FAIL
  • EL6 PHP 7.2: FAIL
  • EL6 PHP 7.3: FAIL (different)
  • EL7 PHP 7.0: PASS
  • EL7 PHP 7.1: PASS
  • EL7 PHP 7.2: PASS
  • EL7 PHP 7.3: PASS (different)

So my best guess is that this test is defunct in some way ¯_(ツ)_/¯

@GusAntoniassi
Copy link

GusAntoniassi commented Dec 13, 2018

I managed to build a Docker image that is able to reproduce this issue.

docker pull gusantoniassi/php-meminfo-memory-leak-bug
docker run -it --rm gusantoniassi/php-meminfo-memory-leak-bug bash
cd /opt/php-meminfo/extension/php7
make test
# test dump-memory_leak.phpt should fail

As you can see from the Dockerfile the installation is pretty minimal, so I believe it is either an issue with EL6 or with the remirepo.net's PHP packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants