我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

今天花了一个上午看了下解决内存问题的代码,相对来说,我对自己的代码的优化很不满意,一次性导入4万条数据,代码这么繁琐,我觉得这个不是根本的解决办法,通过网上搜索,对问题进行了进一步的分析:

在PHP内存溢出问题中,前两种方法就不提了(可以参考博客园的《关于PHP内存释放问题》)。不难分析出问题的关键在于如何在循环中同步释放内存,而不是几百次循环后才释放一次。因为大家在调试中会发现,如果我们把循环中复用性较高的代码封装成函数,再使用调用子函数的形式,程序的执行速度会降低大约几十倍。这个降低的程度会随着数据量的大小而变化。

在嵌套循环的形式下,在处理大量数据的数组时,很多情况下会使用unset($a)来及时释放内存,但其实这样做是没有意义的,下面引用分析:

“在引擎中,变量名和其值其实是两个不同的概念,值本身是一个未命名的zval*存储体(本例中是一个字符串值),通过()赋值给变量$a。如果两个变量名都指向同一个值会怎么样呢?

zval *;

();

(,“你好,世界”,1);

(EG(),“a”,(“a”),&,(zval*),NULL);

(EG(),“b”,(“b”),&,(zval*),NULL);

此时你其实可以查看$a或者$b,发现它们都包含字符串“Hello World”。很遗憾,接下来你继续执行第三行代码“unset($a);”。此时unset()并不知道$a变量指向的数据也被其他变量使用,所以只是盲目的释放内存。之后对变量$b的任何访问都会被解析为已经释放的内存空间,从而导致引擎崩溃。

这个问题可以借助 zval 的第四个成员(有几种形式)来解决。当变量首次创建并赋值时,它会被初始化为 1,因为它被假定仅由最初创建它的变量使用。当你的代码片段开始将 $b 赋值给 $b 时,它需要将 $b 的值增加到 2;因此,该值现在由两个变量引用:

zval *;

();

(,“你好,世界”,1);

(EG(),“a”,(“a”),&,(zval*),NULL);

();

(EG(),“b”,(“b”),&,(zval*),NULL);

现在,当 unset() 删除原始变量 $a 的相应副本时,它可以从参数中看到其他人对该数据感兴趣;因此,它应该减少计数并保持不变。

综上所述,我们最需要做的就是减少最初存放数据的数组。上面的例子中,循环过程中及时释放数组中已经处理完的元素。这样内存使用量会随着循环而波动(内存回收机制问题),但不会一直增长,从而达到了我们最初的目的。当然,一次处理的最大数据量还是取决于服务器分配给PHP的内存,如果一次读入数组的数据量超过了限制,就算是神也无能为力,哈哈

二维码
扫一扫在手机端查看

本文链接:https://by928.com/2230.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线