php 内存引用,释放问题

作者: Renew全栈工程师 | 来源:发表于2020-07-09 04:41 被阅读0次

在一般的场景中,php作为一个脚本,执行完毕就会释放调所有的内存,所以一般我们也不会太考虑内存问题,对象 数组随便复制引用

但是现在如果我们换到了swoole 或者其他的进程式的程序栈中,我们如何保证内存不会越来越高,或者如果我们要自己写一套高效率的框架,那我们的内存到底如何分配才合理

带着这些疑问,我就就行了一下测试,得出了一下结论,供大家参考

1.对象何时销毁

<?php

class AObject
{
    public function print()
    {
        echo "A 对象活着!\n";
    }
}

class BObject
{

    private $aObject;

    public function __construct(AObject &$aObject)
    {
        $this->aObject = &$aObject;
    }

    public function print()
    {
        echo is_null($this->aObject) ? "A对象已经被销毁" : "A对象还存在";
    }
}

echo "开始运行时候的内存大小:" . memory_get_usage() . "\n";

$aObject = new AObject();

echo "创建A对象了的内存大小:" . memory_get_usage() . "\n";

$bObject = new BObject($aObject);

echo "创建B对象并且传入A对象的内存大小:" . memory_get_usage() . "\n";

$bObject->print();

$aObject = null;

$bObject->print();

echo "销毁B对象后的内存大小:" . memory_get_usage() . "\n";


image.png

注意,传值必须是双 & 取内存地址,否则少一个都释放不了,还有一点,如果对象里面不牵扯到【修改】外部传入的变量值时候,尽量不要取内存地址,因为直接传入比在取内存地址要少占用内存!
【但是】这就是绝对了吗,继续往下看看

2.内存引用问题

<?php

echo "开始运行时候的内存大小:" . memory_get_usage() . "\n";

$a = [];

for ($i = 0; $i < 100; $i++) {
    $a[] = $i;
}

echo "创建A数组,里面100个元素后的内存大小:" . memory_get_usage() . "\n";

$c = $a;

echo "c数组直接 copy一个a数组后的内存大小:" . memory_get_usage() . "\n";

$c[0] = 5000;

echo "修改c数组里面的第一个元素后的内存大小:" . memory_get_usage() . "\n";

image.png

可以看出,直接copy是不占内存的,还是a,但是我现在修改c数组之后,你可以看看,内存直接狂增,这是为什么呢,因为php如果传入的不是内存地址的话,修改是修改本数组,但不能修改之前的数组,所以他必须copy一个新的数组,然后再修改,所以,如果不牵扯修改的话,推荐第一种传值方式,直接传入,如果要修改数组的话,原数组影响不影响也无所谓的话,建议取内存地址进行修改,下面给你看看,取内存地址修改后的内存大小

<?php

echo "开始运行时候的内存大小:" . memory_get_usage() . "\n";

$a = [];

for ($i = 0; $i < 100; $i++) {
    $a[] = $i;
}

echo "创建A数组,里面100个元素后的内存大小:" . memory_get_usage() . "\n";

$c = &$a;

echo "c数组直接 copy一个a数组后的内存大小:" . memory_get_usage() . "\n";

$c[0] = 5000;

echo "修改c数组里面的第一个元素后的内存大小:" . memory_get_usage() . "\n";

image.png

可以看出,除了c数组copy a数组时候,多占用了一点24b内存,然后修改,内存不会增加

相关文章

  • php 内存引用,释放问题

    在一般的场景中,php作为一个脚本,执行完毕就会释放调所有的内存,所以一般我们也不会太考虑内存问题,对象 数组随便...

  • Controller销毁NSTimer释放的细节

    关于NSTimer释放和内存泄漏的问题。 @(NSTimer)[内存管理,NSTimer释放,循环引用] 首先需要...

  • iOS面试之内存管理大全

    内存管理内容如下: 内存布局 内存管理 数据结构 ARC/MRC 引用计数 弱引用 自动释放池 循环引用 1.内存...

  • iOS面试之内存管理模块

    内存管理内容如下: 内存布局 内存管理 数据结构 ARC/MRC 引用计数 弱引用 自动释放池 循环引用 1.内存...

  • 2020-03-19【内存管理】

    内存管理 内存布局 内存管理方案 数据结构 ARC & MRC 引用计数 弱引用 自动释放池 循环引用 1.内存布...

  • kkbox-ios-dev笔记(三) - 内存管理/代理

    内存管理(一) 内存泄漏:该释放的对象, 没有被释放(已经不再使用的对象, 没有被释放)无效内存引用:内存已经被释...

  • iOS Runtime 数据结构

    ios内存布局 内存管理方案 数据结构 ARC & MRC 引用计数 弱引用 自动释放池 循环引用 ios内存布...

  • OC总结(二)

    一.内存问题(1).内存溢出(2).野指针(过度释放)二.内存管理方式: (1)MRC:手动管理引用计数.对对象完...

  • 内存管理

    内存布局 内存管理方案 数据结构 ARC & MRC 引用计数 弱引用 自动释放池 循环引用 一、内存布局 二、内...

  • iOS进阶教程:内存泄露的检测

    iOS内存这块,虽然系统会自动管理,但是自己代码不严谨,非常容易产生内存泄露、内存释放、循环引用这些类似问题。 介...

网友评论

    本文标题:php 内存引用,释放问题

    本文链接:https://www.haomeiwen.com/subject/xparcktx.html