Ben dairesel başvurular varsa otomatik olarak gerçekleşmesi PHP çöp toplama tetikleyebilir?

4 Cevap php

Ben kurulum için bir yol hatırlamak görünüyor __destruct bu döngüsel başvurular en kısa sürede dış nesne kapsam dışına denk olarak temizlenmelidir olacağını sağlayacak şekilde bir sınıf için. Ancak, inşa basit bir test bu beklediğimden gibi / ümit davranmak olmadığını belirtmek gibi görünüyor.

Dıştaki nesne kapsam dışına düştüğünde PHP doğru onları temizlemek ki böyle bir şekilde kurulum benim sınıfları için bir yolu var mı?

Ben bu kodu yazmak için alternatif yollar arıyor değilim, ben bu yapılabilir olup olmadığını arıyorum, ve eğer öyleyse, nasıl? Ben genellikle dairesel başvurular mümkünse bu tür önlemek için deneyin.

class Bar {
    private $foo;
    public function __construct($foo) {
        $this->foo = $foo;
    }
    public function __destruct() {
        print "[destroying bar]\n";
        unset($this->foo);
    }
}

class Foo {
    private $bar;
    public function __construct() {
        $this->bar = new Bar($this);
    }
    public function __destruct() {
        print "[destroying foo]\n";
        unset($this->bar);
    }
}

function testGarbageCollection() {
    $foo = new Foo();
}

for ( $i = 0; $i < 25; $i++ ) {
    echo memory_get_usage() . "\n";
    testGarbageCollection();
}

Çıktı şuna benzer:

60440
61504
62036
62564
63092
63620
 [ destroying foo ]
 [ destroying bar ]
 [ destroying foo ]
 [ destroying bar ]
 [ destroying foo ]
 [ destroying bar ]
 [ destroying foo ]
 [ destroying bar ]
 [ destroying foo ]
 [ destroying bar ]

Ne için umduğu:

60440
 [ destorying foo ]
 [ destorying bar ]
60440
 [ destorying foo ]
 [ destorying bar ]
60440
 [ destorying foo ]
 [ destorying bar ]
60440
 [ destorying foo ]
 [ destorying bar ]
60440
 [ destorying foo ]
 [ destorying bar ]
60440
 [ destorying foo ]
 [ destorying bar ]

UPDATE:

Orada PHP> 5.3 ile ilgili bu soruya birkaç büyük cevaplar, ama ben PHP

4 Cevap

Nesne geri ediliyor kez __destruct sadece denir, bunun için bunu kullanamaz. Eğer olsa bir manuel temizleme işlevi oluşturabilirsiniz:

class Foo {
  private $bar;
  public function __construct() {
    $this->bar = new Bar($this);
  }
  public function cleanup() {
    $this->bar = null;
  }
  public function __destruct() {
    print "[destroying foo]\n";
  }
}

class Bar {
  private $foo;
  public function __construct($foo) {
    $this->foo = $foo;
  }
  public function __destruct() {
    print "[destroying bar]\n";
  }
}

function testGarbageCollection() {
  $foo = new Foo();
  $foo->cleanup();
}

Ben bu kadar yararlı emin değilim, ama bu gerçekten tek seçenek < 5.3

http://docs.php.net/features.gc.collecting-cycles:

When the garbage collector is turned on, the cycle-finding algorithm as described above is executed whenever the root buffer runs full. The root buffer has a fixed size of 10,000 possible roots (although you can alter this by changing the GC_ROOT_BUFFER_MAX_ENTRIES constant in Zend/zend_gc.c in the PHP source code, and re-compiling PHP). When the garbage collector is turned off, the cycle-finding algorithm will never run. However, possible roots will always be recorded in the root buffer, no matter whether the garbage collection mechanism has been activated with this configuration setting.

http://docs.php.net/features.gc.performance-considerations:

First of all, the whole reason for implementing the garbage collection mechanism is to reduce memory usage by cleaning up circular-referenced variables as soon as the prerequisites are fulfilled. In PHP's implementation, this happens as soon as the root-buffer is full, or when the function gc_collect_cycles() is called.

5.3 yana you can