【发布时间】:2013-03-12 21:06:02
【问题描述】:
我在这里有一些时间,我正在尝试在自己之后正确清理 (;)),并显示我的类和方法正在使用多少内存。
我遇到的问题是:
- 好像清理之后,比上次内存检查(Pre-Return Memory)使用的内存还多)
这是课程、测试页面和结果(以及在线结果)
类:
<?php
class o7thDB {
public $Type = 1; // What type of database are we connecting to
public $Host = ''; // The host server we are connecting to
public $Name = ''; // The name of the database
public $User = ''; // The user to login with
public $Pass = ''; // The password to login with
public $Query = ''; // The query to execute
public $Params = array(); // An array of parameters to pass to the query for execution
public $ShouldCache = false; // Should the results be cached?
public $CacheKey = ''; // What should we name the key for this cache?
public $Exceptions = ''; // Returns a string representing the exception that occurred if any
/* Memory Usage Tests */
public $InitialMemory;
public $PreSelectMemory;
public $CreatePDOMemory;
public $PostSelectMemory;
public $PreReturnMemory;
protected $DBHandle;
protected $Cache;
protected function Connect(){
$this->InitialMemory = memory_get_peak_usage();
if(session_status() != PHP_SESSION_ACTIVE){
session_start();
}
$dsn = array();
switch ($this->Type) {
case 1: // MS SQL
$dsn = array("mssql:host=$this->Host;dbname=$this->Name", $this->User, $this->Pass);
break;
case 2: // MS SQL Server
$dsn = array("sqlsrv:server=$this->Host;database=$this->Name", $this->User, $this->Pass);
break;
case 3: // MS Access
$dsn = array("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=$this->Name;Uid=$this->User");
break;
case 4: // Oracle
$dsn = array("OCI:dbname=$this->Name;charset=UTF-8", $this->User, $this->Pass);
break;
case 5: // Informix
$dsn = array("informix:DSN=$this->Name", $this->User, $this->Pass);
break;
case 6: // Firebird
$dsn = array("firebird:dbname=$this->Host:$this->Name", $this->User, $this->Pass);
break;
case 7: // MySQL
$dsn = array("mysql:host=$this->Host;dbname=$this->Name", $this->User, $this->Pass);
break;
case 8: // SQLLite
$dsn = array("sqlite:$this->Host");
break;
default: // MySQL
$dsn = array("mysql:host=$this->Host;dbname=$this->Name", $this->User, $this->Pass);
break;
}
try{
$this->DBHandle = new PDO($dsn[0], $dsn[1], $dsn[2]);
$this->DBHandle->setAttribute(PDO::ATTR_PERSISTENT, true);
$this->DBHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->CreatePDOMemory = memory_get_peak_usage();
} catch (PDOException $e) {
$this->Exceptions = $e->getMessage();
}
}
// Destroying Everything
public function __destruct(){
unset($this->DBHandle, $this->Cache, $this->Type, $this->Host, $this->Name, $this->User, $this->Pass,
$this->Query, $this->Params, $this->ShouldCache, $this->CacheKey, $this->Exceptions);
}
// Executes a query against the database, returns boolean success
public function Execute(){
}
// Executes a select statement against the database, returns an associative array
public function Select(){
$this->Connect();
$this->PreSelectMemory = memory_get_peak_usage();
$stmt = $this->DBHandle->prepare($this->Query);
$stmt->execute($this->Params);
$ret = $stmt->fetchAll(PDO::FETCH_ASSOC);
$this->PostSelectMemory = memory_get_peak_usage();
if($this->ShouldCache){
$cKey = $this->CacheKey . session_id();
if(isset($this->Cache[$cKey])){
$this->PreReturnMemory = memory_get_peak_usage();
return $this->Cache[$cKey];
}else{
$this->PreReturnMemory = memory_get_peak_usage();
$this->Cache[$cKey] = $ret;
return $ret;
}
}else{
$this->PreReturnMemory = memory_get_peak_usage();
return $ret;
}
$stmt->closeCursor();
unset($stmt, $ret);
}
}
?>
测试页:
<?php
// Show All Errors
error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once($_SERVER['DOCUMENT_ROOT'] . '/Database/o7th.db.class.php');
// Time the Execution
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
$db = new o7thDB();
$db->Type = 7;
$db->Host = 'localhost';
$db->Name = 'mydb';
$db->User = 'myun';
$db->Pass = 'mypw';
$db->Query = "Select * From `modx_session` Where `data` Like ? Or `id` Like ?";
$db->ShouldCache = true;
$db->CacheKey = 'a';
$db->Params = array('%a%', '%Welcome%');
$ret = $db->Select();
$rCt = count($ret);
echo $rCt . ': Records Returned<br />';
echo $db->Exceptions;
unset($ret);
echo $db->InitialMemory . ': Initial Memory<br />';
echo $db->CreatePDOMemory . ': Create PDO Memory<br />';
echo $db->PreSelectMemory . ': Pre-Select Memory<br />';
echo $db->PostSelectMemory . ': Post-Select Memory<br />';
echo $db->PreReturnMemory . ': Pre-Return Memory<br />';
unset($db);
echo memory_get_peak_usage() .': After all is said and done!<br />';
echo '<hr />';
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "This page was created in ".$totaltime." seconds";
?>
测试页结果:
21168: Records Returned
288016: Initial Memory
288016: Create PDO Memory
288016: Pre-Select Memory
19209456: Post-Select Memory
19209552: Pre-Return Memory
19209768: After all is said and done!
This page was created in 0.066221952438354 seconds
所以,我的问题是,为什么代码在清理之后占用了更多的内存?
【问题讨论】:
-
这可能是一个愚蠢的问题.. 但是.. 当您的脚本返回(因此不执行当前代码路径)时,您如何期望为“PostReturnMemory”设置一个值?跨度>
-
... 当 __destruct 被调用时.. 'this' 指针不会消失吗?所以'PostDestructMemory'实际上将不再存在......会吗?
-
:) 是的,我想的差不多,但是从我为测试页面发布的代码中可以看出,我也在运行内存检查......它仍然在那里事实上,比为 Pre-Return Memory 发布的内容更多......即使在清理发生之后
-
是的,那是 DOH 之一! (砰的一声放在桌子上)时刻。我的 Destruct Memroy 实例将永远不会显示,Post-Return 也不会显示。我现在将编辑 Q
-
Er... memory_get_peak_usage() 给出了内存 peak,即脚本分配的最大值。如果您改用memory_get_usage(),结果会改变吗?
标签: php memory-management memory-leaks pdo