Skip to content

Instantly share code, notes, and snippets.

@NewEXE
Last active September 15, 2018 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NewEXE/ca4f5ddbeb7ff863b8c775c238698c57 to your computer and use it in GitHub Desktop.
Save NewEXE/ca4f5ddbeb7ff863b8c775c238698c57 to your computer and use it in GitHub Desktop.
PDO Memory Leak
<?php
// Related SO disscussion:
// https://stackoverflow.com/questions/52348483/pdo-mysqli-memory-leak-on-multiple-select-queries
$dbParams = [
'host' => 'localhost',
'dbname' => 'playground',
'username' => 'homestead',
'password' => 'secret',
];
$dsn = "mysql:host={$dbParams['host']};dbname={$dbParams['dbname']}";
$pdo = new \PDO($dsn, $dbParams['username'], $dbParams['password']);
$pdo->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
$pdo->exec('
CREATE TABLE IF NOT EXISTS temp_table (
id INT AUTO_INCREMENT PRIMARY KEY,
text VARCHAR (255) NOT NULL
)
');
$i = 0;
while (true) {
$randStr = str_random(255);
$pdo->exec("insert into temp_table(text) values ('$randStr')");
$id = $pdo->lastInsertId();
file_put_contents(__FILE__ . '.log', 'Memory: ' . memory_get_usage_in_mb() . PHP_EOL, FILE_APPEND);
// In test1.php.log:
// Memory: 0.39
// Memory: 0.39
// Memory: 0.39
// And so 20,000 lines...
// Without any memory leaks!
if ($i === 20000) {
break;
}
$i++;
}
function str_random($length = 16)
{
$string = '';
while (($len = strlen($string)) < $length) {
$size = $length - $len;
$bytes = random_bytes($size);
$string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
}
return $string;
}
function memory_get_usage_in_mb()
{
return round(memory_get_usage() / 1024 / 1024, 2);
}
<?php
$dbParams = [
'host' => 'localhost',
'dbname' => 'playground',
'username' => 'homestead',
'password' => 'secret',
];
$dsn = "mysql:host={$dbParams['host']};dbname={$dbParams['dbname']}";
$pdo = new \PDO($dsn, $dbParams['username'], $dbParams['password']);
$pdo->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
$pdo->exec('
CREATE TABLE IF NOT EXISTS temp_table (
id INT AUTO_INCREMENT PRIMARY KEY,
text VARCHAR (255) NOT NULL
)
');
$i = 0;
while (true) {
$pdo->query("SELECT 1 as m");
file_put_contents(__FILE__ . '.log', 'Memory: ' . memory_get_usage_in_mb() . PHP_EOL, FILE_APPEND);
// In test2.php.log ([line]: message):
// 1: Memory: 0.39
// 5000: Memory: 0.44
// 10000: Memory: 0.51
// 20000: Memory: 0.63
// Memory leak...
if ($i === 20000) {
break;
}
$i++;
}
function memory_get_usage_in_mb()
{
return round(memory_get_usage() / 1024 / 1024, 2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment