File tree 3 files changed +163
-0
lines changed 3 files changed +163
-0
lines changed Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GC 048: Objects with destructor are collected without delay
3
+ --FILE--
4
+ <?php
5
+
6
+ class CycleWithoutDestructor
7
+ {
8
+ private \stdClass $ cycleRef ;
9
+
10
+ public function __construct ()
11
+ {
12
+ $ this ->cycleRef = new \stdClass ();
13
+ $ this ->cycleRef ->x = $ this ;
14
+ }
15
+ }
16
+
17
+ class CycleWithDestructor extends CycleWithoutDestructor
18
+ {
19
+ public function __construct ()
20
+ {
21
+ parent ::__construct ();
22
+ }
23
+
24
+ public function __destruct ()
25
+ {
26
+ new CycleWithoutDestructor ();
27
+ }
28
+ }
29
+
30
+ echo "--- \n" ;
31
+
32
+ $ cycleWithoutDestructor = new CycleWithoutDestructor ();
33
+ $ cycleWithoutDestructorWeak = \WeakReference::create ($ cycleWithoutDestructor );
34
+ $ cycleWithDestructor = new CycleWithDestructor ();
35
+ $ cycleWithDestructorWeak = \WeakReference::create ($ cycleWithDestructor );
36
+ gc_collect_cycles ();
37
+
38
+ echo "--- \n" ;
39
+
40
+ unset($ cycleWithoutDestructor );
41
+ var_dump ($ cycleWithoutDestructorWeak ->get () !== null );
42
+ gc_collect_cycles ();
43
+ var_dump ($ cycleWithoutDestructorWeak ->get () !== null );
44
+
45
+ echo "--- \n" ;
46
+
47
+ unset($ cycleWithDestructor );
48
+ var_dump ($ cycleWithDestructorWeak ->get () !== null );
49
+ gc_collect_cycles ();
50
+ var_dump ($ cycleWithDestructorWeak ->get () !== null );
51
+ --EXPECT --
52
+ ---
53
+ ---
54
+ bool (true )
55
+ bool (false )
56
+ ---
57
+ bool (true )
58
+ bool (false )
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GC 049: Objects created during GC do not participate in the same collection
3
+ --FILE--
4
+ <?php
5
+
6
+ class CycleWithDestructor
7
+ {
8
+ private \Closure $ destructorFx ;
9
+
10
+ private \stdClass $ cycleRef ;
11
+
12
+ public function __construct (\Closure $ destructorFx )
13
+ {
14
+ $ this ->destructorFx = $ destructorFx ;
15
+ $ this ->cycleRef = new \stdClass ();
16
+ $ this ->cycleRef ->x = $ this ;
17
+ }
18
+
19
+ public function __destruct ()
20
+ {
21
+ ($ this ->destructorFx )();
22
+ }
23
+ }
24
+
25
+ $ isSecondGcRerun = false ; // https://github.com/php/php-src/commit/b58d74547f
26
+ $ createFx = static function () use (&$ createFx , &$ isSecondGcRerun ): void {
27
+ $ destructorFx = static function () use (&$ createFx , &$ isSecondGcRerun ): void {
28
+ if (!gc_status ()['running ' ]) {
29
+ echo "gc shutdown \n" ;
30
+ return ;
31
+ }
32
+
33
+ echo "gc " . ($ isSecondGcRerun ? ' rerun ' : '' ) . "\n" ;
34
+
35
+ $ isSecondGcRerun = !$ isSecondGcRerun ;
36
+
37
+ $ createFx ();
38
+ };
39
+
40
+ new CycleWithDestructor ($ destructorFx );
41
+ };
42
+
43
+ $ createFx ();
44
+ gc_collect_cycles ();
45
+ gc_collect_cycles ();
46
+ gc_collect_cycles ();
47
+ echo "--- \n" ;
48
+ gc_collect_cycles ();
49
+ gc_collect_cycles ();
50
+ gc_collect_cycles ();
51
+ echo "--- \n" ;
52
+ ?>
53
+ --EXPECT--
54
+ gc
55
+ gc rerun
56
+ gc
57
+ gc rerun
58
+ gc
59
+ gc rerun
60
+ ---
61
+ gc
62
+ gc rerun
63
+ gc
64
+ gc rerun
65
+ gc
66
+ gc rerun
67
+ ---
68
+ gc shutdown
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GC 050: Destructor are never called twice
3
+ --FILE--
4
+ <?php
5
+
6
+ class G
7
+ {
8
+ public static $ v ;
9
+ }
10
+
11
+ class WithDestructor
12
+ {
13
+ public function __destruct ()
14
+ {
15
+ echo "d \n" ;
16
+
17
+ G::$ v = $ this ;
18
+ }
19
+ }
20
+
21
+ $ o = new WithDestructor ();
22
+ $ weakO = \WeakReference::create ($ o );
23
+ echo "--- \n" ;
24
+ unset($ o );
25
+ echo "--- \n" ;
26
+ var_dump ($ weakO ->get () !== null ); // verify if kept allocated
27
+ G::$ v = null ;
28
+ echo "--- \n" ;
29
+ var_dump ($ weakO ->get () !== null ); // verify if released
30
+ ?>
31
+ --EXPECT--
32
+ ---
33
+ d
34
+ ---
35
+ bool(true)
36
+ ---
37
+ bool(false)
You can’t perform that action at this time.
0 commit comments