PHP PDO类内存使用情况

时间:2013-03-22 21:17:06

标签: php memory-management memory-leaks pdo

我在这里有点时间,我正在尝试在自己(;)之后正确清理,并显示我的班级和方法正在使用多少内存。

我遇到的问题是:

  1. 似乎在清理之后,使用的内存比最后一次内存检查(预返回内存)更多。)
  2. 这是课程,测试页面和结果(以及在线结果)

    CLASS:

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

    所以,我的问题是,为什么代码会占用更多内存,毕竟清理完毕后呢?

1 个答案:

答案 0 :(得分:-1)

PHP进程不释放已释放的内存。通过释放PHP脚本中的内存,您只需使其可供同一进程使用。但是整个进程总是拥有它在运行时分配的所有内存。

这就是为什么在PHP中不需要自己进行清理 - 无论如何你无法在脚本运行时将它返回到系统,但整个运行时只需要几分之一 - 所以,没有必要打扰。

顺便说一下,你的班级看起来太错了......想象一下 坦率地说,它旨在解决想象中的问题,而不是真正的问题。就像连接到所有可能的数据库一样。同时它缺乏非常重要的东西。

基于会话的缓存机制看起来很糟糕。它确实会用很多的无用数据污染你的记忆。

  • 说,您的网站上有10个页面,每个页面都会保存所有其他页面的缓存数据。
  • 说,一次会有10个用户浏览您的网站 - 因此,您将拥有10个不同文件中存储的10个相同数据的副本。

所有这些重复的“缓存”消耗了你太在意的记忆。

因此,效果将是相反的 - 而不是加速您的网站,这个缓存实际上会使它变得缓慢和臃肿。

这就是为什么说: “过早优化是所有邪恶的根源”