未明确取消设置时的exessive对象内存使用情况

Rij*_*ijk 6 php garbage-collection

我的一位同事写了一个耗尽可用内存的脚本.我将其缩小到以下基本测试用例:

for ( $i = 0; $i <= 20; $i ++ ) {
    echo memory_get_usage(). '<br />';
    $Survey = new Survey( 14 );
    echo memory_get_usage(). '<br /><br />';
}
exit('done');
Run Code Online (Sandbox Code Playgroud)

这打破了第三次迭代:

3116696
49123440

49123440
95518368

95518368
[E_ERROR] Allowed memory size of 134217728 bytes exhausted (tried to allocate 71 bytes)
Run Code Online (Sandbox Code Playgroud)

我设法解决了这个问题,只需unset()在循环中添加一个调用:

for ( $i = 0; $i <= 20; $i ++ ) {
    echo memory_get_usage(). '<br />';
    $Survey = new Survey( 14 );
    unset( $Survey );
    echo memory_get_usage(). '<br /><br />';
}
exit('done');
Run Code Online (Sandbox Code Playgroud)

现在,脚本经历了20次迭代,非常流畅,内存使用相对恒定:

3116816
49123488

49123488
50691656

50691656
51088912

51088912
51079064

51079064
50535368

50535368
50809296

50809296
51033392

51033392
51157208

51157208
50543856

50543856
50892760

50892760
51045160

51045160
51132688

51132688
50535968

50535968
50968632

50968632
51058080

51058080
51143304

51143304
50562136

50562136
51067432

51067432
51067768

51067768
51170824

51170824
50551712

done
Run Code Online (Sandbox Code Playgroud)

这让我很困惑!是不是垃圾收集器应该清理对象,因为它的变量已被覆盖?我正在运行PHP 5.3,所以循环引用不能成为这个问题的原因.

Jon*_*Jon 4

循环引用在 5.3 中仍然是一个问题

清理问题

尽管任何作用域中不再有符号指向该结构,但它无法被清除,因为数组元素“1”仍然指向同一个数组。因为没有外部符号指向它,所以用户无法清理这个结构;因此你会遇到内存泄漏。幸运的是,PHP 会在请求结束时清理这个数据结构,但在此之前,这会占用内存中宝贵的空间。如果您正在实现解析算法或其他让子元素指向“父”元素的东西,这种情况经常会发生。当然,同样的情况也可能发生在对象上,实际上更有可能发生,因为对象总是通过引用隐式使用。

内部可能还有一些占用内存的资源Survey占用了所有这些内存;观察到的行为应该是引用循环和此类资源的组合。

里面到底是什么Survey