2013-03-02 3 views
4

При распаковке gzinflate я обнаружил, что при определенных обстоятельствах обстоятельства - следующий код приводит к ошибкам в памяти. Протестировано с PHP 5.3.20 на 32-разрядном Linux (Amazon Linux AMI на EC2).gzinflate: макс. пространство, чтобы избежать нехватки памяти?

$memoryLimit = Misc::bytesFromShorthand(ini_get('memory_limit')); // 256MB 
$memoryUsage = memory_get_usage(); // 2MB in actual test case 
$remaining = $memoryLimit - $memoryUsage; 
$factor = 0.9; 
$maxUncompressedSize = max(1, floor($factor * $remaining) - 1000); 
$uncompressedData = gzinflate($compressedData, $maxUncompressedSize); 

Хотя, я вычислил размер $maxUncompressedSize консервативно, надеясь дать gzinflate достаточно памяти, я все еще получаю:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 266143484 bytes) in foo.php on line 123

При изменении значения $factor от 0.9 до 0.4, то ошибка будет в этом случае. В других случаях 0.9 в порядке.

Интересно:

Является ли причиной ошибки действительно что gzinflate нуждается более чем в два раза пространство несжатых данных? Возможно, есть еще одна причина? Действительно ли $remaining остальная память в распоряжении для приложения?

+1

Что вы 'gzinflate()' в первую очередь, что такое большое? –

+0

'gzinflate', вероятно, выделяет память на выход, временные блоки данных. Вы должны прочитать его реализацию. – Tchoupi

+1

PHP не является C, вы не можете реально ожидать, что 'gzinflate' и PHP будут нуждаться не больше, чем размер несжатой строки (даже если вы оставите margin). Плюс, PHP довольно свободен, когда дело доходит до памяти, это, скорее всего, нормальное поведение. – Mahn

ответ

1

Это действительно возможно. ИМХО, проблема заключается в memory_get_usage(true).

Использование true должно дать более высокую ценность использования памяти, поскольку должно учитывать все.

Смежные вопросы