Doktrin sorgu bellek kullanımı

7 Cevap php

Doktrin bir tek, basit bir sorgu çalıştırmak için 4MB RAM üzerinde de alıyor gibi görünüyor:

print memory_get_peak_usage()." <br>\n";
$q = Doctrine_Query::create()
    ->from('Directories d')
    ->where('d.DIRECTORY_ID = ?', 5);

$dir = $q->fetchOne();
print $dir['name']." ".$dir['description']."<br>\n";

print memory_get_peak_usage()." <br>\n";

/***************  OUTPUT:  **************************

6393616
testname testdescription
10999648

/***************************************************/

Ben sorgulama am öğe burada görüntülenir ne başka herhangi bir veri içermiyor - Bu da çok az veri ile bir test veritabanı üzerinde.

Ben sistem kurdunuz yolu ile yanlış bir şey, potansiyel var mı, yoksa Doktrini için bu standart bellek kullanımı nedir?

7 Cevap

Görebildiğim kadarıyla, kod yanlış görünmüyor ...


As a test, I've set up a quick example, with a very simple table (only four fields).

İşte ilgili kodu:

var_dump(number_format(memory_get_peak_usage()));

$test = Doctrine::getTable('Test')->find(1);

var_dump(number_format(memory_get_peak_usage()));

Bunu yaparken, ben çıktı bu tür var:

string '1,316,088' (length=9)
string '2,148,760' (length=9)

Tabloyu dikkate alınarak basit ve sadece bir satır getiriliyor olduğumu, bana da "fazla" gibi görünüyor - ama bu ne alıyorsanız oldukça tutarlı, ve ben :-( diğer projeler üzerinde ne gördüm ile


If you only need to display your data, and not work with it (ie update/delete/...), a solution might be to not fetch complex objects, but only a simple array :

$test = Doctrine::getTable('Test')->find(1, Doctrine::HYDRATE_ARRAY);

Ancak, bu durumda, aslında :-(, bir fark çok yapmaz:

string '1,316,424' (length=9)
string '2,107,128' (length=9)

Farkın sadece 40 KB - iyi, daha büyük cisimler / daha hatları ile, hala iyi bir fikir olabilir ...


In the Doctrine manual, there is a page called Improving Performance ; maybe it could help you, especially for these sections :


Oh, btw : I did this test on PHP 5.3.0 ; maybe this can have an impact on the amount of memory used...

Ben romanb yanıt ile katılıyorum - büyük libs / çerçeveler kullanarak bir OpCode önbelleğini kullanarak kesin bir zorunluluktur.

An example related to OpCode caching

Geçenlerde Zend Framework ile Doktrin kullanımını benimsemiş ve bellek kullanımı hakkında merak ettik - yani OP gibi, ben OP testine benzer kriterler kullanılarak bir yöntem oluşturulur ve görmek için genel bir test olarak koştu ne ZF + Doktrini zirve bellek kullanımı olur olacak.

Ben şu sonuçları aldı:

APC olmadan Sonuç:

10.25 megabytes
RV David
16.5 megabytes

APC ile Sonuç:

3 megabytes
RV David
4.25 megabytes

Opcode önbelleğe alma çok önemli bir fark yaratıyor.

Peki, nerede bu bellek kullanımı nereden geliyor? Pascal MARTIN işaret ettiği gibi, dizi hidrasyon biz sadece burada birkaç kayıtları bahsediyoruz ilgili mantıklı büyük bir fark yapmaz.

Bellek tüketimi autoloading aracılığıyla talep üzerine yüklenen tüm sınıflar geliyor.

APC kurmak yok ise, o zaman evet, sistem kurmak yolu ile yanlış bir şey var. Performansını ölçmek ve APC gibi bir opcode önbellek olmadan herhangi bir büyük php kütüphanesi ile iyi sonuçlar beklemek başlar dont bile. Bu yürütme hızlandırmak değil, aynı zamanda (APC ilk baytkodlarına önbelleğe gerekiyor) çok ilki hariç tüm sayfa yükleri en az% 50 oranında bellek kullanımını azaltmak değil sadece.

Ve basit bir örnek ile 4MB gerçekten hiç APC gibi kokuyor, aksi takdirde gerçekten biraz yüksek olacaktır.

Doktrin Query üzerinde fetchone ile Dikkat (). Bu işlev çağrısı SQL üzerinde "Limiti 1" append olmaz

Sadece DB tek kayıtları almak gerekiyorsa, emin olun:

$q->limit(1)->fetchOne() 

Bellek kullanımı büyük masaya bırakılan muazzam.

Önce sonra ilk öğeyi döndürür () bir koleksiyon olarak DB alıp fetchone görebiliyordu.

public function fetchOne($params = array(), $hydrationMode = null)
{
    $collection = $this->execute($params, $hydrationMode);

    if (is_scalar($collection)) {
        return $collection;
    }

    if (count($collection) === 0) {
        return false;
    }

    if ($collection instanceof Doctrine_Collection) {
        return $collection->getFirst();
    } else if (is_array($collection)) {
        return array_shift($collection);
    }

    return false;
}

Ben bellek çoğu sorgu kendisi ile ilişkili nesneler için Doktrini sınıflarını, aslında yükleme kadar kullanıldığını tahmin ediyorum.

  • Doktrin'e hangi sürümünü kullanıyorsunuz?
  • Eğer autoloader kullanıyor musunuz?

Doktrin 1.1, varsayılan autoload davranış sadece belirli bir istek üzerine bir veya iki tane kullanıyor olsanız bile bu modeli tüm sınıfların yüklemek anlamına gelir, 'saldırgan' olarak adlandırılır. 'Muhafazakâr' olarak bu davranışı ayarlama bellek kullanımını azaltacaktır.

Doctrine provides a free() function on Doctrine_Record, Doctrine_Collection, and Doctrine_Query which eliminates the circular references on those objects, freeing them up for garbage collection. More info..

Biraz daha az bellek kullanımı yapmak Sen folowing kodu kullanmayı deneyebilirsiniz:

  • $ Kayıt-> Ücretsiz (true) -, derin ücretsiz-up bulunuyor yapacak (ücretsiz aramalar) tüm ilişkileri üzerinde çok
  • $ Toplama-> Ücretsiz () - bu tüm koleksiyon başvurular özgür olacak
  • Doctrine_Manager :: bağlantısı () -> temiz () / clear () - temizleme bağlantısı (ve kimlik harita girdileri kaldırmak)
  • $ Sorgu-> Ücretsiz ()

Ben sadece Symfony 1.4 ve aşağıdaki ayarı ile komut hogging bellek durdurdu "daemon" did adres:

sfConfig::set('sf_debug', false);