2013-03-22 44 views
0

我在這裏有一段時間,我試圖在自己(;)之後正確清理,並顯示我的類和方法正在使用多少內存。PHP PDO類內存使用

我遇到的問題是這樣的:

  1. 看來,清理後,有比上次內存檢查(預返回存儲器))

下面是使用更多內存課堂上,測試頁面,結果(和業績網上說明)

類:

<?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 

所以,我的問題是,爲什麼是它的代碼使用更多的內存,一切都清理後?

+0

這可能是一個愚蠢的問題..但是..怎麼是你期待有「PostReturnMemory設置的值'當你的腳本正在返回(並因此不執行當前代碼路徑)? – ethrbunny 2013-03-22 21:34:05

+0

...並且__destruct被調用時..不是'this'指針會消失嗎?所以'PostDestructMemory'將不再存在了。是嗎? – ethrbunny 2013-03-22 21:36:53

+0

:)是的,我想盡可能多,但正如你從我發佈的測試頁的代碼中可以看到的,我正在運行內存檢查以及...它仍然在那裏實際上超過什麼張貼爲預迴歸內存......即使在清理結束後仍然存在 – Kevin 2013-03-23 02:37:48

回答

-1

PHP進程不釋放已釋放的內存。通過釋放PHP腳本中的內存,您可以將其提供給相同進程使用。但是整個過程始終擁有它在運行時分配的所有內存。

這就是爲什麼在PHP中不需要清理自己 - 在腳本運行期間無法將其返回系統,但整個運行時間只需要秒的幾分之一 - 因此,沒有任何麻煩的地方。

順便說一下,你的班級看起來太錯了......虛構的一個。坦白說,它的目的是解決想象中的問題,而不是真正的問題。像連接所有可能的數據庫一樣。同時它缺乏真正重要的東西。

而基於會話的緩存機制看起來很糟糕。它確實會污染你的記憶,其中很多無用的數據。

  • 說,網站上有10個頁面,每個頁面都會保存所有其他頁面的緩存數據。假設,一次將有10個用戶瀏覽您的網站 - 因此,您將有10個不同文件中存儲的相同數據的副本。

所有這些衆多複製「高速緩存」 消耗非常記憶你太在意的。

因此,效果會相反 - 而不是加快你的網站這個緩存實際上會讓它變得緩慢和臃腫。

這就是爲什麼人們說:「過早的優化是所有罪惡的根源」