Why does my PHP function execution fail to release the memory?

Source: Internet
Author: User
Why does my PHP function execution fail to release the memory? recently, I made an import large file, because it involves processing the file to obtain the required structure data.
Store a large amount of data in an array.
In the process, the memory consumption is very large, not the memory_limit setting problem. I have set it large enough.
During the processing, you can also disable unset. However, memory_get_usage () is used to compare the memory before and after the function is called.
After the function is called, the memory does not decrease significantly. All the large arrays have been unset. The same is true.
If the number of imported files is small, no memory overflow error occurs. But when the file is large to a certain extent. Because the execution process is in progress,
After the function is called, the memory usage is large. This causes memory overflow.
This makes me a little depressed. After the function is called, haven't all the local variable space been released?
Is there any memory leakage? Does anyone have the same problem. If you have encountered the same problem, or someone else knows. Let's discuss it together. Thank you.
Ps: The score is quite small. this is the only option.


Reply to discussion (solution)

Is unset () an array or an array element?

Also, is the array used in the function a local variable or a global variable?

Also, is the array used in the function a local variable or a global variable?
Well, I have considered all this.
Unset is an array
I also know the unset () global variable in the function.
Just remove the temporary variable in the function.
I have assigned the global $ GLOBALS variable to the unset
Still so
I have never encountered similar problems in my previous work, because I have never handled such big data before.
Now, let me rethink this problem.
Today, I also read the principles of PHP memory management.
I don't know if anyone has ever met

Code...

Code...
The code is too long. let me paste a function.

Function importTestSuiteFormArray1 ($ db, $ parentID, $ tproject_id, $ userID, $ duplicateLogic, & $ testsuiteArray, & $ testcaseArray) {global $ productIndex; $ unexistPF = array (); // platform for storing excel files not found in the current project $ produceRelFB = array (); $ resultMap = null; $ tsResult = null; // test suite import result $ tables = tlObject: getDBTables ("platforms"); $ pfSql = "select id, name from ". $ tables ['platform']. "where testproject_id = $ tproject_id"; $ pfRe = $ Db-> fetchcolumns1_map ($ pfSql, "id", "name"); $ pfRe = is_null ($ pfRe )? Array (): $ pfRe; foreach ($ productIndex as $ vKey => $ pItem) {if (! In_array ($ vKey, $ pfRe) {$ unexistPF [] = $ vKey ;}// $ memory1 = memory_get_usage (); // $ fileName = date ("md-His"); // $ hand = fopen ("e:/testcase /". $ fileName. ". txt "," a + "); // $ bTime = microtime_float (); $ tempTSArray = array (); $ createSuc =" created successfully. "; $ UpdateSuc =" update successful. "; If (is_array ($ testsuiteArray) & count ($ testsuiteArray)> 0) {foreach ($ testsuiteArray as $ key => $ tsItem) {// $ begin = microtime_float (); if ($ tsItem ['name']! = "") {If ($ tsItem ['parentnum'] = 0) {$ parID = $ parentID ;} else {$ parID = $ tempTSArray [$ key] ['parentid'];} $ tsuiteMgr = new testsuite ($ db ); $ info = $ tsuiteMgr-> get_by_name ($ tsItem ['name'], $ parID); if (is_null ($ info )) {$ ret = $ tsuiteMgr-> create ($ parID, $ tsItem ['name'], "", $ tsItem ['node _ order']); $ tsuiteID = $ ret ['id']; $ tsResult [] = array ($ tsItem ['name'], $ createSuc );} else {$ tsuiteID = $ info [0] ['id']; $ ret = $ tsuiteMgr-> update ($ tsuiteID, $ tsItem ['name'], "", null, $ tsItem ['node _ order']); $ tsResult [] = array ($ tsItem ['name'], $ updateSuc );} if (is_array ($ tsItem ['Children ']) & count ($ tsItem ['Children'])> 0) {foreach ($ tsItem ['Children '] as $ val) {$ tempTSArray [$ val] ['parentid'] = $ tsuiteID ;}}} // $ end = microtime_float (); // fwrite ($ hand, "for each protocol :". ($ end-$ begin ). "\ r \ n") ;}}// echo "before testsuiteArray ". memory_get_usage ()."
"; $ TestsuiteArray = null; // echo" after testsuiteArray ". memory_get_usage ()."
"; $ GLOBALS ['testsuitearray'] = null; // echo" after global testsuiteArray ". memory_get_usage ()."
"; If (is_array ($ testcaseArray) & count ($ testcaseArray)> 0) {$ tcData = array (); // $ begin = microtime_float (); $ flag = 0; foreach ($ testcaseArray as $ key => $ tsItem) {if ($ tsItem ['parentnum'] = 0) {$ parID = $ parentID ;} else {$ parID = $ tempTSArray [$ key] ['parentid'];} $ tcData [$ flag] = array ("name" => $ tsItem ['name'], "node_order" => $ tsItem ['order'], "parentID" => $ parID); if (is_array ($ tsItem ['properties']) & count ($ tsItem ['properties'])> 0) {foreach ($ tsItem ['properties'] as $ pKey => $ val) {$ tcData [$ flag] [$ pKey] = $ val ;}} if (is_array ($ tsItem ['m M _ Fields']) & count ($ tsItem ['m M _ fields '])> 0) {foreach ($ tsItem ['m M _ fields'] as $ cfName => $ cfValue) {$ tcData [$ flag] [customfields] [] = array ("name" =>$ cfName, "value" =>$ cfValue );}} if (is_array ($ tsItem ['srs ']) & count ($ tsItem ['srs'])> 0) {$ tcData [$ flag] ['srs '] = $ tsItem ['srs'];} if (is_array ($ tsItem ['produce']) & count ($ tsItem ['produce'])> 0) {$ tcData [$ flag] ['produce'] = $ tsItem ['produce'];} $ flag ++;} // $ end = microtime_float (); // fwrite ($ hand, "Cycle case time :". ($ end-$ begin ). "\ r \ n"); // echo "before testcaseArray ". memory_get_usage ()."
"; $ TestcaseArray = null; // echo" after testcaseArray ". memory_get_usage ()."
"; $ GLOBALS ['testcasearray'] = null; // echo" after global testcaseArray ". memory_get_usage ()."
"; $ TempTSArray = null; // echo" after tempTSArray ". memory_get_usage ()."
"; If (is_array ($ tcData) & count ($ tcData)> 0) {// $ begin = microtime_float (); $ resultMap = saveImportedTCData1 ($ db, $ tcData, $ tproject_id, $ userID, null, $ duplicateLogic, $ produceRelFB, $ pfRe); $ tcData = null; // echo "after tcData ". memory_get_usage ()."
"; // $ Memory2 = memory_get_usage (); // $ end = microtime_float (); // fwrite ($ hand," total time of saving use cases :". ($ end-$ begin ). "\ r \ n"); // fwrite ($ hand, "Total time :". ($ end-$ bTime ). "\ r \ n"); // fwrite ($ hand, "memory consumption :". ($ memory2-$ memory1 ). "\ r \ n") ;}$ return = array ("resultMap" =>$ resultMap, "tsResult" =>$ tsResult, "unexistPF" =>$ unexistPF, "produceRel" => $ produceRelFB); return $ return; // return $ resultMap ;}

My note: $ testsuiteArray and $ testcaseArray are the analysis files and the obtained arrays. The two arrays may contain dozens of MB or hundreds of MB.
The problem is that the array is too large. you can use other methods. The problem is that after I call this function and the saveImportedTCData1 function in this function, the memory of saveImportedTCData1 is not significantly reduced after the call. I have tried to destroy all the returned results and the referenced variables, and the memory usage is large, resulting in overflow. The code is very tired. thank you.

Someone else...

Refer
Http://www.laruence.com/2011/03/04/1894.html

Refer
Http://www.laruence.com/2011/03/04/1894.html
Haha, I have read this article and have also studied what the blogger said.
It indicates that the table is occupied by the symbol. Then I want to release the symbolic table.
I am asking the blogger. Thank you for your reply.

After file analysis, the array occupies 20 MB.
Then the database operation involves a lot of operations.
After Execution, the memory size is nearly 1 GB larger than the initial one.
Is there any exception in this result.
Unnecessary data is unset during processing.

In fact, after careful analysis
The arrays are released after the call.
Why does the call occupy so much memory?
Is there a large number of database operations?
--

Ask a question, 3Q

5000 arrays, with more information in each array.
Performed more than database operations and more than 40 seconds of database execution time
Use cyclic operations.
The memory for each array operation increases gradually.
It is reasonable to say that the local variables used in each loop are the same.
Only the array that saves the database operation results increases, but the increase is small.
It is impossible to require that large memory.
Where does the extra memory usage come from?
Until the function is called. These memory spaces are not released. why?
Why? Why? Why?
I am troubled by this bottleneck.

Experienced
Great success, big brother and uncle
How does the extra memory come from?
HELP .....

Try to release the database connection, which may be occupied by database operations.

Try to release the database connection, which may be occupied by database operations.
The same is true if the database is released.
Does this intermediate operation cause memory leakage?
Is there a situation like this?

I have encountered a memory leak in create_function before, but it is useless here.

This can only be adjusted by yourself,
You have installed xdebug with several functions to help analyze the memory.

I want to blow it up --
Think too much

Check the space occupied by $ return that carries the returned value.

Check the space occupied by $ return that carries the returned value.
Returned Value $ return is unset
It still occupies a lot of resources.

$resultMap=saveImportedTCData1($db,$tcData,$tproject_id,$userID,null,$duplicateLogic,$produceRelFB,$pfRe);

The memory size before and after this function call varies greatly.
I unset the returned result $ resultMap, $ tcData, and the data associated with $ produceRelFB.
After a function is called, isn't all the temporary space allocated when it is executed released. How can this happen. I cannot figure it out. Where is the memory? Where are you --

Let's take a look at php's garbage collection mechanism.

Let's take a look at php's garbage collection mechanism.
As early as I was a student, I learned about java gc.
Php gc has long known a mechanism similar to java.
I don't think so.
I think we should go deep into the php kernel to study the php memory allocation mechanism.

When xdebug is used, only the execution is implemented without memory.
I used WinCacheGrind. exe to view
I still can't find it --

If you have not processed such big data
With so many database operations
These problems cannot be encountered in General Systems.
This feature is not commonly used.
But as a management tool
Sometimes it is necessary to perform such a few big data processing times.
I think this is a solution.
It should be another growth that will pay more attention to efficiency and other problems.
Be sure to solve
I feel so lonely and talking to myself --

Your function also calls other user-defined functions and instantiated user-defined classes, which may cause problems.
You have to troubleshoot the problem one by one.

Check this function saveImportedTCData1 to see if it is caused by internal problems.
In addition, if the data is obtained from the database, will the record set resources be released ......

Thank you for your answers.
Custom classes and functions are correct.
In fact, the biggest problem is saveImportedTCData1 in this function.
I released all the output produced by this function.
Even if the memory usage output through meomory_get_usage () is released, it is still n times the memory usage before calling this function.
It is about an order of magnitude larger.
Check this function.
Can xdebug view memory consumption through WinCacheGrind?
I didn't see any memory

Thank you again
Ps: Actually, if Baidu and Google can find the answer I want, I will not ask. I found that most of the questions I asked were not answered. I have learned a lot about communication with you. Try again to find the cause.

?????.

Check it out by yourself. this outsider is really not helpful, especially you don't know how to write your saveImportedTCData1.
Add reference transfer and test again. it may be because the variable is separated once in your function, and the variable itself is large.
$ ResultMap = saveImportedTCData1 ($ db, & $ tcData, $ tproject_id, $ userID, null, $ duplicateLogic, & $ produceRelFB, $ pfRe );

Check it out by yourself. this outsider is really not helpful, especially you don't know how to write your saveImportedTCData1.
Add reference transfer and test again. it may be because the variable is separated once in your function, and the variable itself is large.
$ ResultMap = saveImportedTCData1 ($ db, & $ tcData, $ tproject_id, $ userID, null, $ duplicateLogic, & $ produc ......
Well, my function prototype is just in $ tcData, which is referenced with $ produceRelFB.

I checked it.
The above function has line of code

  $tcData[$flag][customfields][] = array("name"=>$cfName,"value"=>$cfValue);

[Customfields] I forgot to add quotation marks. I remember reading the manual mentioned this problem, which may cause low efficiency.
Because php requires a lot of additional checks. So it is always used to quotation marks. You may accidentally forget it.
As a result, the overhead of a large amount of data is suddenly different. I calculated the overhead of the space by 20 times. The time overhead is not counted.
The problem still persists.

After xdebug and re-debugging analysis
Final problem solved

Thanks to all of the above friends

Admire the landlord

But how does the landlord solve it? I recently encountered a similar problem.

I also asked the landlord how to solve the problems mainly caused by those problems.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.