memory_limit的一个bug | 风雪之隅
27 Nov 09 memory_limit的一个bug
- 作者: Laruence(
)
- 本文地址: http://www.laruence.com/2009/11/27/1164.html
- 转载请注明出处
PHP 5.2x中, 由于错误的选用了zend_atoi, 导致memory_limit不能设置为超过4G的值.
今天同事分享给我一个问题(thans to yanmi), 一段代码(PHP 5.2.11 Linux/X86_64),设置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;
- ...
最后, 如果是32位的机器, 那确实不算bug, 但现在的机器很多都64了, 最大内存也不再是4GB了, PHP也要与时俱进啊.
PS, 多看别人的代码是有好处的, 今天有学会了intentionally这个单词, ^_^.
document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?t=" + new Date().getHours();
Related Posts:
- 深入理解PHP内存管理之谁动了我的内存
- PHP类型转换相关的一个Bug
- Nginx + PHP CGI的一个可能的安全漏洞
- 深入理解PHP原理之对象(一)
- PHP5.2.x + APC的一个bug的定位
- 提升PHP性能之改变Zend引擎分发方式
- PHP文件上传源码分析(RFC1867)
- 深入理解PHP原理之错误抑制与内嵌HTML
- HTTPOXY漏洞说明
- 让你的PHP7更快(GCC PGO)
memory_limit的一个bug | 风雪之隅的更多相关文章
- 【风雪之隅】写在PHP7发布之际一些话 2015-12-02
做开源也有4,5年的时间了,从最初的 Yaf,到今天的 PHP7,我参与的项目越来越多,使用我代码的用户也越来越多,明天就要发布的PHP7,绝对是我从事开源以来的一个最重要里程碑,我应该纪念一下今天, ...
- Tomcat一个BUG造成CLOSE_WAIT
之前应该提过,我们线上架构整体重新架设了,应用层面使用的是Spring Boot,前段日子因为一些第三方的原因,略有些匆忙的提前开始线上的内测了.然后运维发现了个问题,服务器的HTTPS端口有大量的C ...
- MySQL关于exists的一个bug
今天碰到一个很奇怪的问题,关于exists的, 第一个语句如下: SELECT ) FROM APPLY t WHERE EXISTS ( SELECT r.APPLY_ID FROM RECORD ...
- 由一个bug引发的SQLite缓存一致性探索
问题 我们在生产环境中使用SQLite时中发现建表报“table xxx already exists”错误,但DB文件中并没有该表.后面才发现这个是SQLite在实现过程中的一个bug,而这个bug ...
- Win10系统菜单打不开问题的解决,难道是Win10的一个Bug ?
Win10左下角菜单打不开,好痛苦,点击右下角的时间也没反应,各种不爽,折磨了我好几天,重装又不忍心,实在费劲,一堆开发环境要安装,上网找了很多方法都不适用.今天偶然解决了,仔细想了下,难道是Win1 ...
- 你可能不知道的 NaN 以及 underscore 1.8.3 _.isNaN 的一个 BUG
这篇文章并不在我的 underscore 源码解读计划中,直到 @pod4g 同学回复了我的 issue(详见 https://github.com/hanzichi/underscore-analy ...
- 标准模板库(STL)的一个 bug
今天敲代码的时候遇到 STL 的一个 bug,与 C++ 的类中的 const 成员变量有关.什么,明明提供了默认的构造函数和复制构造函数,竟然还要类提供赋值运算符重载.怎么会这样? 测试代码 Tes ...
- 是uibutton跟tableviewcell同步使用一个bug
这个问题是uibutton跟tableviewcell同步使用一个bug,不关delay一点毛事,证据就是点击事件没问题,so,搜到一个方法解决了这个问题.uibutton分类symbian2+ios ...
- 在chrome下-webkit-box布局的一个bug
chrome,也就是webkit内核下作的检测, chrome版本是40, -webkit-box这种布局在移动端用的比较多,主要是因为pc端的浏览器内核参差不齐. 因为在写HTML的时候看上了-we ...
随机推荐
- 如何在 .Net Framework 4.0 项目上使用 OData?
最新的 Microsoft ASP.NET Web API 2.1 OData 5.1.0 已只能在 .Net Framework 4.5 的安装了,如果要在 VS2010的 .Net Framewo ...
- BZOJ3755 : Pty爬山
l[i],r[i]表示站在i点往左往右走能看到的最高峰,用栈维护凸壳求出 h[i]表示i点能看到的最高峰的高度 a[i],b[i]表示i点往左往右走时反悔的点,即第一个h[j]>h[i]的j,用 ...
- Git 远程操作详解
Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能. Git有很多优势,其中之一就是远程操作非常简便.本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌握Gi ...
- winform学习之----重新绘制边框方法延伸
方法1. Pen pen1 = new Pen(Color.FromArgb(233, 149, 87)); e.Graphics.DrawRectangle(pen1, new ...
- 转 c# 日期函数[string.Format----GetDateTimeFormats]格式 .
DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:21:25Label2.Text = dt.ToFileTi ...
- mysql5.6安装
mysql5.6安装 #卸载原有的mysqlyum remove mysql*ls /etc/my.cnf*mv /etc/my.cnf* /tmp/ #安装依赖包yum install make c ...
- Linux下LDAPSearch的例子
apt-get install ldap-utils LdapSearch examples The following examples are taking from various ldapse ...
- Apache Spark源码走读之11 -- sql的解析与执行
欢迎转载,转载请注明出处,徽沪一郎. 概要 在即将发布的spark 1.0中有一个新增的功能,即对sql的支持,也就是说可以用sql来对数据进行查询,这对于DBA来说无疑是一大福音,因为以前的知识继续 ...
- 在 MySQL 中查找含有目标字段的表
要查询数据库中哪些表含有目标字段,可以使用语句: SELECT TABLE_SCHEMA,TABLE_NAME FROM information_schema.`COLUMNS` WHERE COLU ...
- sqrt函数实现
感谢杨工,让我更加认识到自己技术薄弱,这道题源自于和杨工的非正式面试,当时根本没思路,甚至没和查找有丝毫的联系,看来做自己想做的还是要付出努力的.sqrt()即开平方运算,y=x*x,已知Y的情况下求 ...