php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #34112 Memory leak when initiating COM object and then destroying it
Submitted: 2005-08-12 23:53 UTC Modified: 2005-08-15 18:26 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: James_Brigham at hotmail dot com Assigned:
Status: Not a bug Package: COM related
PHP Version: 5.0.4 OS: Windows 2000 or Windows 2003
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: James_Brigham at hotmail dot com
New email:
PHP Version: OS:

 

 [2005-08-12 23:53 UTC] James_Brigham at hotmail dot com
Description:
------------
I have not compiled any additional modules.  The recommended default php.ini is being used.  There is a memory leak when initiating a new COM object, then running a query against it.  After the query even if you use the unset()function on all the variables, you cannot recover the full memory, it just keeps climbing.  Do you have any ideas of how to clear the memory in this simple code I have below?

Thanks for taking the time to read this, it is appreciated.

JB


Reproduce code:
---------------
#!c:\php5\ -q
<?php

$aryHost 		= array("cp2kisu01","cp2kisu02","cp2kisu03"); //this is a list of servers running IIS 5 on a windows 2000 platform
$sProcName 		= "dllhost"; //give the name of the process to check
$wmi			= ""; //our comm object
$threadRecords	= ""; //comm object result set
$threadcount	= ""; //temp variable for looping though each return record.

echo("\r\n\r\n" . str_repeat("*",79) . "\r\n");
echo("Program Start\r\n"); //this is written for command line...
echo("\r\n" . str_repeat("*",79) . "\r\n");
while(true) //loop until the end of time
{
	for ($i = 0; $i < count($aryHost); $i++) //loop through each server in the array
	{
		$wmi = new COM("WinMgmts:{impersonationLevel=impersonate}//{$aryHost[$i]}/root/cimv2"); //initialize new COM object
		$threadRecords = $wmi->ExecQuery("SELECT * FROM Win32_PerfRawData_PerfProc_Process WHERE Name = '" . $sProcName . "'"); //execute a wmi query against our com object
		foreach ($threadRecords as $threadcount) //loop through the resules
		{
			echo("Server:[" . $aryHost[$i] . "] Name: " . $threadcount->Name . " Count: " . $threadcount->ThreadCount . "\r\n"); //for each result output basic info to the screen
		}
		echo("\r\nClearing all the used memory for server: " . $aryHost[$i] . "\r\n\r\n");
		unset($wmi); //clear object memory
		unset($threadRecords); //clear returned records memory
		unset($threadcount); //clear our temp variable we use for our loop
	}
	
	echo("\r\n\r\n" . str_repeat("*",79) . "\r\n");
	echo("Sleeping.. so we can check the amount of memory consumed now..\r\n"); //this is written for command line...
	echo("\r\n" . str_repeat("*",79) . "\r\n");
	sleep(15); //sleep to keep this from being a tight loop and give time to check the memory loss each loop
}
?>

Expected result:
----------------
D:\Appsupport\IIS_Monitor>php wmi.php


*******************************************************************************
Program Start

*******************************************************************************
Server:[cp2kisu01] Name: dllhost Count: 318
Server:[cp2kisu01] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu01

Server:[cp2kisu02] Name: dllhost Count: 318
Server:[cp2kisu02] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu02

Server:[cp2kisu03] Name: dllhost Count: 333
Server:[cp2kisu03] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu03



*******************************************************************************
Sleeping.. so we can check the amount of memory consumed now..

*******************************************************************************
Server:[cp2kisu01] Name: dllhost Count: 317
Server:[cp2kisu01] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu01

Server:[cp2kisu02] Name: dllhost Count: 310
Server:[cp2kisu02] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu02

Server:[cp2kisu03] Name: dllhost Count: 328
Server:[cp2kisu03] Name: dllhost Count: 10

Clearing all the used memory for server: cp2kisu03



*******************************************************************************
Sleeping.. so we can check the amount of memory consumed now..

*******************************************************************************
^C
D:\Appsupport\IIS_Monitor>

Actual result:
--------------
we gets the counts expected.. but we have a memory loss every run from this very simple script.  Basically I would like to be able to loop this across 20 servers every 45 seconds.. but with the memory consumption I cannot feasibly do that.  Every added server causes loss of additional memory.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-08-13 00:17 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip


 [2005-08-13 00:27 UTC] James_Brigham at hotmail dot com
As suggested, I have downloaded the latest release from:
 http://snaps.php.net/win32/php5-win32-latest.zip
and I still see the same memory leak.
 [2005-08-13 00:31 UTC] James_Brigham at hotmail dot com
if you comment out the query lines, then the memory leak seems to go away...

the lines I commented out were:
//$threadRecords = $wmi->ExecQuery("SELECT * FROM Win32_PerfRawData_PerfProc_Process WHERE Name = '" . $sProcName . "'"); //execute a wmi query against our com object
//foreach ($threadRecords as $threadcount) //loop through the resules
//{
//echo("Server:[" . $aryHost[$i] . "] Name: " . $threadcount->Name . " Count: " . $threadcount->ThreadCount . "\r\n"); //for each result output basic info to the screen
//}
 [2005-08-13 01:00 UTC] sniper@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is not something unique to COM but general 'problem' of PHP. All memory is really cleaned up after request is ended.

 [2005-08-13 01:06 UTC] James_Brigham at hotmail dot com
Could you explain what you mean by "request is ended"?  I would have thought that the request is ended by the time I received my result set.  Then after I have my result set, I unset it...
 [2005-08-15 18:17 UTC] James_Brigham at hotmail dot com
I feel the answer to this problem is very vague and the true problem is being ignored and glossed over.
 [2005-08-15 18:26 UTC] sniper@php.net
Any memory any PHP function reserves during the REQUEST (the one you start when you either run a script from command line or access it via web) it frees AFTER the script has been run.
This is expected behaviour -> not bug.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 02:01:30 2024 UTC