0

我在这里度过了一段时间,我正在尝试在自己之后进行适当的清理 (;)),并显示我的类和方法正在使用多少内存。

因此,我遇到的问题是:

  1. 好像清理后比上次内存检查使用的内存多(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

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

4

1 回答 1

-1

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

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

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

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

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

由于所有这些大量重复的“缓存”消耗了您过于关心的内存。

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

这就是为什么说:“过早的优化是万恶之源”

于 2013-04-05T12:40:07.647 回答