memory leak v php (pri 1000-nasobnom volani fcie)

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Matúš Matula
Člen | 257
+
0
-

Viem, ze je to trochu OT, ale snad mi niekto pomoze.
Mam problem s memory leak, kt. sa vyskytuje v nasledujucom pripade. Mam metodu, kt. predavam 2 argumenty – 1D pole a integer. Vsetko, co metoda robi je, ze prenasobi kazdy prvok pola premennou $multiplier a zmenene pole vrati. Tuto metodu volam v skripte radovo tisicky krat, pricom za kazdym volanim sa par bajtov ukroji z pamate a neuvolni sa. Prisiel som na to, ked mi spadlo php na memory limite 512MB :) Podozrievam php z toho, ze neuvolnuje alokovanu pamat pre premennu $tmp po ukonceni metody.

<?php
public static function arrayScalarMultiply($arr, $multiplier)
{
	$tmp = array();
	foreach ($arr as $k=>$v) {
		$tmp[$k] = $v * $multiplier;
	}
	return $tmp;
}

//a takto ju volam v cykloch
$ret[$k][$n][$i] = MyArrayTools::arrayScalarMultiply($code1D[$k][$element1D], $code1D[$t][$v][$i]);
?>

Nejake napady?

norbe
Backer | 405
+
0
-

Není to náhodou tím, že výsledek volání funkce si ukládáš zase do pole? :)

Matúš Matula
Člen | 257
+
0
-

to si nemyslim. vysledne pole ma rozmery: 86416*16 * 4B (integer) = 524.288kB ale zozerie to 11MB.
Nasledne pri vacsich rozmeroch pola: 1625632*32 * 4B (integer) = 16.7MB ale zozerie to 354.06MB :))

Uvazujem zle?

newPOPE
Člen | 648
+
0
-

Tiez si myslim ze to co tvrdi @norbe s tym nieco ma. su tam rozne indexy volania tej metody cize mi to pride ze zdrojove pole ostane a este aj prenasobene ukladas. cize hned 2× zdrojove pole.

Fakt ze podla vypoctov to sice vychadzaju smiesne velkosti ale ktovie co sa tam vsetko este alokuje (tam uz nevidim :-D)

nepomoze ti ked budes to zdrojove prepisovat (mozno referencie?.) ? alebo ho potrebujes?

alebo ho pri navrate serializovat, je asi chu**na :-D

paranoiq
Člen | 392
+
0
-

@MM:

  1. otestuj to bez ukládání a odpověď máš hned
  2. paměťová náročnost pole v PHP je několikanásobně vyšší než tvůj jednoduchý (čéčkovský) odhad. pole je implementováno jako slovník a to i v případě, kdy obsahuje pouze indexy typu int. nejlepší by bylo přepsat úlohu tak, aby data zpracovávala po částech a ukládala
Matúš Matula
Člen | 257
+
0
-

@paranoiq: dik za objasnenie, zase som mudrejsi. spravil som to, ako si navrhol s ciastkovym ukladanim.

srigi
Nette Blogger | 558
+
0
-

Kazdopadne by si ale ten cyklus mal zoptimalizovat – pomocnu premenuu neni treba, ukladaj to priamo cez referenciu:

public static function arrayScalarMultiply($arr, $multiplier)
{
    foreach ($arr as &$v) {
        $v *= $multiplier;
    }

    return $arr;
}

A teoreticky by si mohol aj to vstupne pole predat referenciou:

public static function arrayScalarMultiply(&$arr, $multiplier)
{
  // telo fncie
  // return vynechat!
}

$foo = $code1D[$k][$element1D];
MyArrayTools::arrayScalarMultiply($foo, $code1D[$t][$v][$i]);
$ret[$k][$n][$i] = $foo;
tenerd
Člen | 15
+
0
-

Co pouzit fci array_map (http://php.net/…rray-map.php)?

Matúš Matula
Člen | 257
+
0
-

@srigi: povodne tam pomocna premenna nebola, skusal som potom rozne variacie, zerie to ale rovnako pamate – je totiz jedno ci iterujes cez referenciu, alokuje sa rovnake mnozstvo pamati (kedze hodnotu menis).
cele vstupne pole predat referenciou nemozem, pretoze ho nemozem menit – pouziva sa v skripte niekolko krat. na druhej strane som skusal predat aj 3. argument referenciou, do kt. ukladat vysledok, ale @norbe mal pravdu a @paranoiq mi to aj vysvetlil – pamat zerie ukladanie do vysledneho pola.
@tenerd: array_map je to iste len v ruzovom.

este raz pisem – VYRIESENE. Dik vsetkym za reakcie.