2009-08-29 2 views
23

Es gibt eine Möglichkeit, den gesamten von PHP verwendeten Speicher zu erhalten (memory_get_usage()), aber wie erhält man die Speichergröße eines einzelnen Objekts?Größe im Speicher eines Objekts in PHP erhalten?

Ich spreche natürlich nicht über count(), wie ich die Anzahl der Bytes in einer potenziell komplexen Datenstruktur will.

Antwort

15

Sie können memory_get_usage() vor und nach dem Zuordnen Ihrer Klasse aufrufen, wie in this example from IBM dargestellt. Sie könnten sogar einen Wrapper dafür erstellen und das Ergebnis möglicherweise für eine Membervariable der komplexen Klasse selbst speichern.

EDIT:

Um den Teil über die Speicherung der zugewiesenen Speichergröße zu verdeutlichen, können Sie etwas tun:

class MyBigClass 
{ 
    var $allocatedSize; 
    var $allMyOtherStuff; 
} 

function AllocateMyBigClass() 
{ 
    $before = memory_get_usage(); 
    $ret = new MyBigClass; 
    $after = memory_get_usage(); 
    $ret->allocatedSize = ($after - $before); 

    return $ret; 
} 

An jedem Punkt in der Zukunft, könnten Sie allocatedSize überprüfen, um zu sehen, wie groß Dieses Objekt war zum Zeitpunkt der Zuweisung. Wenn Sie jedoch nach dem Zuweisen hinzufügen, wäre allocatedSize nicht mehr korrekt.

+1

Was ist, wenn PHP beschließt, den Speicher freizugeben, der gerade zur "falschen Zeit" reserviert wurde? Ich weiß nicht wirklich, wann PHP Speicher freigibt (irgendwie "wenn nötig", nehme ich an), aber ich denke, dass diese Freigabe einige Probleme bringen könnte? Besonders mit dem Garbage Collector von PHP 5.3 für zyklische Referenzen? –

+0

Nun ja, aber zusätzlich zu dem, was Pascal erwähnt, möchte ich in der Lage sein, dies zu verschiedenen Zeiten herauszufinden, nicht nur zur Zeit der Zuweisung. Ich möchte das in vielen Zeilen auf der Straße herausfinden. –

+0

@Pascal: PHP wird keinen Speicher freigeben, der immer noch von einem aktiven Objekt referenziert wird. Zyklische Referenzen bedeuten A Referenzen B und B Referenzen A, aber nichts anderes verweist auf A oder B. So wird Speicher nicht freigegeben, solange das Programm noch auf irgendeine Weise darauf verweisen kann. –

3

Ich glaube nicht, dass dies durchaus möglich ist; Ich habe noch nie etwas gesehen, mit dem Sie die Größe eines Objekts im Speicher finden könnten.

Eine Lösung, um eine ziemlich grobe Idee zu bekommen, könnte sein, Ihre Daten zu serialisieren, und verwenden Sie strlen auf ... Aber das wird wirklich etwas von einer Schätzung sein ... Ich würde mich nicht auf irgendetwas wie verlassen dass, eigentlich ...


Auch debug_zval_dump macht das nicht: es ouput die Daten in einer variablen und der refcount, aber nicht der Speicher verwendet:

$obj = new stdClass(); 
$obj->a = 152; 
$obj->b = 'test'; 

echo '<pre>'; 
debug_zval_dump($obj); 
echo '</pre>'; 

werden Sie nur bekommen:

object(stdClass)#1 (2) refcount(2){ 
    ["a"]=> 
    long(152) refcount(1) 
    ["b"]=> 
    string(4) "test" refcount(1) 
} 
+0

Sehr interessant. Meine nächste Frage war eigentlich, Refcounts zu bekommen, um herauszufinden, warum es ein Speicherleck gibt. Vielen Dank! –

11

Wäre es nicht sinnvoll, das Objekt zu serialisieren und die Stringlänge zu lesen? Offensichtlich wird es einige Bytes aus sein, weil die serialisierte Zeichenkette s hätte: 'string' deshalb s: '' sind zusätzliche Bytes ... es sei denn, die Serialisierung könnte genauso sein, wie PHP Objekte speichert.

so zum Beispiel

$size = strlen(serialize($object)); 

Nur so ein Gedanke?

Ein weiterer chaotisch, aber möglicherweise genau Gedanken:

eine Klasse Instanzvariable Unter der Annahme, dass ein paar Mal seit Instanziierung manipuliert wurde:

$DB; // database access class for eg. 
$mem = memory_get_usage(); 
$DB_tmp = clone $DB; 
$mem = memory_get_usage() - $mem; 
unset($DB_tmp); 

$ könnte mem die genaue Größe des Speichers auf $ DB zugeordnet sein ;

+0

** Klon ** funktioniert nicht für mich (ich weiß nicht warum). Es meldet immer 100 Bytes nach dem Klonen eines Objekts. –

1

Da Klon (von Prof83's answer) nicht für mich arbeiten, habe ich versucht, serialisiert und unserialize die Variable, deren Größe Ich möchte messen:

function getMemoryUsage($var) { 
    $mem = memory_get_usage(); 
    $tmp = unserialize(serialize($var)); 
    // Return the unserialized memory usage 
    return memory_get_usage() - $mem; 
} 

Ich denke, es bessere Ergebnisse berichtet, zumindest für mich.

+0

Sie haben die Variable '$ tmp' nicht verwendet –

0

Wenn Sie nur die Größe des Objekts wissen wollen, und nicht für Ihren nächsten Code, return es an den Browser, und Sie können sehen, wie viel das Netzwerk senden das Objekt.