• 技术文章 >后端开发 >php教程

    php为什么运行了一段时间后才报内存溢出?

    2016-12-01 00:56:49原创811
    我一次性从数据库读取了10万条数据,然后循环做一些计算,循环过程中,涉及到的变量都会被下次循环覆盖掉,现在的情况是程序运行了一段时间之后,报内存溢出,为什么不是刚开始的时候就报内存溢出?按照我的理解,我并没有用变量一直去存运算结果,所以如果说内存溢出的话,应该就在一开始就报了啊。

    回复内容:

    我一次性从数据库读取了10万条数据,然后循环做一些计算,循环过程中,涉及到的变量都会被下次循环覆盖掉,现在的情况是程序运行了一段时间之后,报内存溢出,为什么不是刚开始的时候就报内存溢出?按照我的理解,我并没有用变量一直去存运算结果,所以如果说内存溢出的话,应该就在一开始就报了啊。

    php version 5.5+

    例:

    for($i = 1; $i <= 10; $i += 1)
            yield $i;

    在php中其实变量都是通过zval变量来保存,zend_uint refcount__gc 是该变量中的一个计数器,用来保存有多少变量。在变量生成时,其refcount=1,典型的赋值操作如$a = $b会令zval的refcount加1,而unset操作会相应的减1。在PHP5.3之前,使用引用计数的机制来实现GC,如果一个zval的refcount较少到0,那么Zend引擎会认为没有任何变量指向该zval,因此会释放该zval所占的内存空间。但,事情有时并不会那么简单。后面我们会看到,单纯的引用计数机制无法GC掉循环引用的zval,即使指向该zval的变量已经被unset,从而导致了内存泄露。

    你在循环覆盖变量的时候,其实本质的recount值并没有减少,所以所占用内存并没有释放,最后肯定会爆炸。

    解决方案:

    ini_set(‘memory_limit’,’1024M’);
    

    问题分析:

    =。=没代码怎么分析。。。
    

    可能原因:

    读取数据不要时间啊?
    变量覆盖之前生成的临时对象就不占内存啊?

    你从数据库读取10w条数据的时候,估计就已经内存不足了吧

    我印象中变量重新赋值,内存中的对象数据其实会COPY一份,用unset或者GC才会释放,不过我没找到相关资料。
    内存占用因素很多,PHP是动态语言,内存管理操作是隐藏的,你用同一个变量看似用同一个内存区域,但事情上并不是。

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:php
    上一篇:TP为什么通过ajax提交后显示未定义? 下一篇:大量多级分类数据的获取、缓存、搜索查询 怎么设计最快 ?
    Web大前端开发直播班

    相关文章推荐

    • php js 文本框 值增减有关问题• PHP的mcrypt模块装配• php与redis施用经验分享• 请教 zend框架 怎么 整合 FCKeditor编辑器啊• php基础学习- 一些废弃的用法封锁提高性能

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网