Free up memory in php

Asked

Viewed 1,903 times

0

Is it possible to free up memory in PHP? In a method I run some functions between them a foreach and after I finish wanted to free up memory.

I’m unset on some variables but I don’t recover l space again.

It is possible ?

Edit I will explain my intention to release the memory:

In the system I am developing I need to return details of a period that can reach up to 1 year term. Showing day by day the status of each block of time, and can one day have up to 96 blocks.

Part of this code is a method that returns me an array containing part of this detailing.

And this code is consuming about 50 megas ... Look at the code:

public function getRenovacao($grades_id, $periodo_inicio, $periodo_fim, $atividades_comerciais_id) {

        Controller::startTest();
        Controller::checkPointStartTest('Laço While');

        $end_timestamp = strtotime($periodo_fim);
        $tmp_timestamp = strtotime($periodo_inicio);
        while ($tmp_timestamp <= $end_timestamp) {
            $tmp_dia_semana = (int) date("w", $tmp_timestamp);
            $tmp_data = date("Y-m-d", $tmp_timestamp);
            $periodo_array[$tmp_dia_semana][$tmp_data] = ['atividade_comercial_utilizada' => 0, 'duracao_utilizada' => 0];
            $tmp_timestamp = strtotime("+1 day", $tmp_timestamp);
        }

        Controller::checkPointEndTest();
        Controller::checkPointStartTest('Consulta banco de dados tabela "Blocos"');
        $select = 
                [
                    'blocos.grades_id',
                    'blocos.bloco',
                    'blocos.dia_semana',
                    'blocos.duracao',
                    'blocos_produtos.blocos_id',
                    'blocos_produtos.produtos_id',
                ];

        $grade_blocos = DB::table('blocos')
                ->join('blocos_produtos', 'blocos.id', '=', 'blocos_produtos.blocos_id')
                ->select($select)
                ->where('blocos.grades_id', $grades_id)
                ->get();

        $grade_blocos = json_decode(json_encode($grade_blocos),1);

        foreach ($grade_blocos as $dados) {
            if(array_key_exists($dados['dia_semana'], $periodo_array)){
                $key = (int)$dados['blocos_id'];
                $blocos[] = $dados['blocos_id'];
                $tmp_grade_blocos[$key]['id'] = $dados['blocos_id'];
                $tmp_grade_blocos[$key]['grades_id'] = $dados['grades_id'];
                $tmp_grade_blocos[$key]['bloco'] = $dados['bloco'];
                $tmp_grade_blocos[$key]['dia_semana'] = $dados['dia_semana'];
                $tmp_grade_blocos[$key]['duracao'] = $dados['duracao'];
                $tmp_grade_blocos[$key]['produtos'][] = $dados['produtos_id'];
                $tmp_grade_blocos[$key]['programacao'] = $periodo_array[$dados['dia_semana']];
            }
        }
        $grade_blocos = array_values($tmp_grade_blocos);
        $blocos = array_unique($blocos);

        unset($periodo_array, $tmp_grade_blocos, $tmp_data, $tmp_dia_semana, $tmp_timestamp,$end_timestamp);

        Controller::checkPointEndTest();
        Controller::checkPointStartTest('Consulta banco de dados tabela "Comerciais"');


        $blocos_tempo = DB::table('comerciais')
                ->join('produtos', 'comerciais.produtos_id', '=', 'produtos.id')
                ->select('blocos_id', 'atividades_comerciais_id', 'data', 'produtos.duracao')
                ->whereIn('blocos_id', $blocos)
                ->where('data', '>=', $periodo_inicio)
                ->where('data', '<=', $periodo_fim)
                ->get();

        Controller::checkPointEndTest();
        Controller::checkPointStartTest('Laço Foreach Final');

        foreach ($blocos_tempo as $dados) {
            $id = $dados->blocos_id;
            $grade_blocos_id = array_search($id, array_column($grade_blocos, 'id'));

            $tmp_data = $dados->data;
            $tmp_atividades = (int)$grade_blocos[$grade_blocos_id]["programacao"][$tmp_data]['atividade_comercial_utilizada'];
            if($dados->atividades_comerciais_id == $atividades_comerciais_id){
                $tmp_atividades++; 
            }

            $tmp_duracao_utilizada = (int)$grade_blocos[$grade_blocos_id]["programacao"][$tmp_data]['duracao_utilizada'] + (int)$dados->duracao;
            $grade_blocos[$grade_blocos_id]["programacao"][$tmp_data] =
                                                                        [
                                                                            'atividade_comercial_utilizada' => $tmp_atividades,
                                                                            'duracao_utilizada' => $tmp_duracao_utilizada
                                                                        ];
        }

        Controller::checkPointEndTest();
        Controller::endTest();
        //die();
        $return['grades_id'] = $grades_id;
        $return['blocos'] = $grade_blocos;

Where checkpoint and test are static functions only to measure consumption, I made them myself to know which piece of code to improve ... See the result:

Laço While ----------------------------------------------------- Running time: 0.00576 s. Initial memory: 9.25 MB. Final Memory: 9.5 MB. Memory Used: 0.25 MB. -----------------------------------------------------

Consulta banco de dados tabela "Blocos"
-----------------------------------------------------
Tempo de execução: 0.0788 s.
Memoria inicial: 9.5 MB.
Memoria Final: 18.75 MB.
Memoria Utilizada: 9.25 MB.
-----------------------------------------------------

Consulta banco de dados tabela "Comerciais"
-----------------------------------------------------
Tempo de execução: 0.54036 s.
Memoria inicial: 18.75 MB.
Memoria Final: 49 MB.
Memoria Utilizada: 30.25 MB.
-----------------------------------------------------

Laço Foreach Final
-----------------------------------------------------
Tempo de execução: 2.20804 s.
Memoria inicial: 49 MB.
Memoria Final: 50.25 MB.
Memoria Utilizada: 1.25 MB.
-----------------------------------------------------

TEMPO TOTAL DE EXECUÇÃO DO SCRIPT
-----------------------------------------------------
Tempo de execução: 2.83315 s.
Memoria inicial: 9.25 MB.
Memoria Final: 50.25 MB.
Memoria Utilizada: 41 MB.
----------------------------------------------------
  • The programming routine seems flawless, the bottleneck is in the bank. I have sql routines with almost 200 lines that consume 300ms of execution in an advertising system that I own. Print the entire sql query and also check if you have correctly set the indices in the related tables. Unless you have me fooled : Execution time: 0.54036 s. is second or milestones?

  • 0.54 seconds is right ?

  • @Rafaelsalomão yes ... At least that’s what is returning me the test in this excerpt ... The strange thing is that is consuming a lot of memory in this query

  • How many records does the Commercial table have? This table is myisam or innodb?

  • @Rafaelsalomão 151.000 record I use innodb

  • @Daniellopes must be related to the first one you did and why there you did not put the amount of record because it influences.

  • related: https://answall.com/questions/143602

Show 3 more comments

1 answer

1

Daniel does not need to worry about the memory release of php he manages it. In reality when a theards of apache Nginx or lighttpd runs it runs php as a child that runs its php routines at the end of the run the return is returned to the http server and printed on the page and the server itself repurposes the opened php head to run other requests that are coming to the server. Or if there is no need shuts down open theards to release memory usage this process is named GARBAGE COLLECTOR.

The command:

unset

serves only if you want to release the value of a variable to reuse it in your script.

PS: theards = processing head.

This was a very superficial explanation of how it works there are several ways to run php like cgi, fastcgi for example, if you want to delve into google ways to run php on apache or any web server.


I’ll give you several solutions the first is debugging to note the problem:

copy your COMMERCIAL table and put another name then delete much of your content as well as the records that relate to that table then edit your code for the new table name and run its routine. If you see time going by you’ll spot where the bottleneck is :

Solution 1 : Partition the table

Solution 2: Create a new table and "pre-execute" the data of this Join with stored Procedure and create an event in the database to run in background updates, when to run your query run through this new table a simple query

Solution 3: I never used but I know there is use view.

It remains to be sure that your sql is right, as it uses a container class I had no way to analyze the construction of the query.

I hope this information is useful.

  • I’m worried because a method I’m using is spending 50 megas ... A part that I put a foreach consumes about another 15 megas ... So I’m trying to optimize the code, even though it’s fast in its execution. So I’m afraid that a moment later when I have to run this foreach with twice the data may cause a fatal error by memory consumption

  • put the code and let’s see why ! = P

  • thank you very much for your attention ... I edited the question is put complementary information and the code also ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.