Autor | Zpráva | ||
---|---|---|---|
Martin Dostal Profil |
Ahoj,
potřeboval bych poradit ohledně práce s pamětí v php. Mam v Php napsaný vlastní redakční systém a teď jsem na hostingu narazil na následující chybovou hlášku: Fatal error: Allowed memory size of 41943040 bytes exhausted (tried to allocate 71 bytes) .. a spuštěno na řádku, kde se rekurzivně volá funkce: // TATO FCE MI ZJISTI VSECHNY RODICE OD ROOTU AZ K AKTUALNI SEKCI function RecursiveGetParent($section, $list) { //echo "volam re. parent pro: ".$section; // je rodic uz mezi hlavnima sekcema ? $main_section = $this->LoadSectionInfoForNavigation($section); if ($main_section == null) { // neni to mezi hlavnima, ale je mezi podsekcema $parent_section = $this->LoadSubSectionInfo($section); //printr($parent_section); $list[] = $parent_section["internal_name"]; $parent_section_name = $parent_section["parent_section"]; unset($parent_section); return $this->RecursiveGetParent($parent_section_name, $list); } else { $list[] = $main_section["internal_name"]; unset($main_section); //echo "vracim list:"; //printr($list); return $list; } } Všude se snažím uvolňovat pamět s využitím unset u proměnných a s mysql_free_result($result); u dotazů na MySql. Když jsem měřil velikost použité paměti, tak mi to vyšlo asi na 2 MB s využitím fce: memory_get_usage. Lze tu paměť ještě nějak ušetřit? Případně, kdy přesně se dealokuje paměť pro proměnné použité ve skriptu? Já jsem si myslel, že se uvolní paměť, která je použitá v proceduře, ihned po ukončení procedury. Jinak vim, že ta rekurze v Php asi neni ideální, ale tímto způsobem můžu vytvořit strom sekcí na celém webu. |
||
Davex Profil |
#2 · Zasláno: 20. 6. 2008, 22:23:50
Problém bude v řádku
$list[] = $parent_section["internal_name"]; Při každém rekurzivním volání se udělá další kopie celého pole a spotřeba paměti kvadraticky narůstá. |
||
Martin Dostal Profil |
#3 · Zasláno: 22. 6. 2008, 10:12:26
Tak tuhle rekurzi jsem už odstranil a nahradil jí while cyklem. A do tohoto pole to přidávam přes pomocnou proměnnou, tak už by to snad neměl být problém.
Ještě by mi zajímala jedna věc: mám několik objektů, které mi zajišťují určité "knihovní" funkce a občas se tyto objekty musí volat navzájem. Je lepší, aby k sobě přistupovali přes globální proměnné, nebo aby se vždy v dané funkci vytvořily nové instance? // v kodu $b = new B(); $a = new A(); class A { function DataFromB() { global $b; $b->GetData(); } } nebo class B { $a = new A(); $a->GetData(); unset($a); } Snažil jsem se to najít v manuálech a na webu, ale nikde neni řečeno, co je paměťově výhodnější. Jestli použití globální proměnné ukousne nějaký větší kus paměti, který zůstane blokován apod. |
||
Časová prodleva: 16 let
|
0