技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> PHP --> memory_limit的一个bug

memory_limit的一个bug

浏览:2267次  出处信息

PHP 5.2x中, 由于错误的选用了zend_atoi导致 memory_limit不能设置为超过4G的值.

今天同事分享给我一个问题(thans to yanmi), 一段代码, 设置memory_limit为4096M会导致内存耗尽, 而设置4095M就不会. 奇怪的问题呵.

那是怎么回事呢?

问题的原因也很简单, 在PHPSRC/main.c中定义的memory_limit设置项的处理器OnChangeMemoryLimit中, 使用了zend_atoi来做为字符串数字化, 这个问题在PHP5.3的版本中已经修正(换成了zend_atol):

以下是代码片段:
static PHP_INI_MH(OnChangeMemoryLimit)
{
    if (new_value) {
        PG(memory_limit) = zend_atoi(new_value, new_value_length);
    } else {
        PG(memory_limit) = 1<<30;       /* effectively, no limit */
    }
    return zend_set_memory_limit(PG(memory_limit));
}

而, 顾名思义么, atoi是转成整形, 4096M是2的32次方, 发生溢出导致结果为0, zend_atoi代码如下:

以下是代码片段:
ZEND_API int zend_atoi(const char *str, int str_len)
{
    int retval;

    if (!str_len) {
        str_len = strlen(str);
    }
    retval = strtol(str, NULL, 0);
    if (str_len>0) {
        switch (str[str_len-1]) {
            case ’g’:
            case ’G’:
                retval *= 1024;
                /* break intentionally missing */
            case ’m’:
            case ’M’:
                retval *= 1024;
                /* break intentionally missing */
            case ’k’:
            case ’K’:
                retval *= 1024;
                break;
        }
    }
    return retval;
}

最后在zend_set_memory_limit的时候, 会错误的设置memory_limit为mm_heap的blok_size, 那结果就肯定远远小与你所预期的4096M了

以下是代码片段:
....
 AG(mm_heap)->limit = (memory_limit >= AG(mm_heap)->block_size) ? memory_limit : AG(mm_heap)->block_size;
...

PS, 多看别人的代码是有好处的, 今天有学会了intentionally这个单词, ^_^.

建议继续学习:

  1. Linux内存点滴 用户进程内存空间    (阅读:11598)
  2. ps - 按进程消耗内存多少排序    (阅读:11356)
  3. Linux Used内存到底哪里去了?    (阅读:10021)
  4. Linux操作系统的内存使用方法详细解析    (阅读:8921)
  5. linux内核研究笔记(一)内存管理 – page介绍    (阅读:8766)
  6. 几个内存相关面试题(c/c++)    (阅读:8073)
  7. 内存越界的概念和调试方法    (阅读:6343)
  8. Innodb分表太多或者表分区太多,会导致内存耗尽而宕机    (阅读:6203)
  9. 必看!linux系统如何查看内存使用情况    (阅读:6204)
  10. 如何查看Linux 硬件配置信息    (阅读:5925)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1