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这个单词, ^_^.
建议继续学习:
- Linux内存点滴 用户进程内存空间 (阅读:11598)
- ps - 按进程消耗内存多少排序 (阅读:11356)
- Linux Used内存到底哪里去了? (阅读:10021)
- Linux操作系统的内存使用方法详细解析 (阅读:8921)
- linux内核研究笔记(一)内存管理 – page介绍 (阅读:8766)
- 几个内存相关面试题(c/c++) (阅读:8073)
- 内存越界的概念和调试方法 (阅读:6343)
- Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读:6203)
- 必看!linux系统如何查看内存使用情况 (阅读:6204)
- 如何查看Linux 硬件配置信息 (阅读:5925)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:PHP截取图片的某个区域
后一篇:如何在PHP下载文件名中解决乱码 >>
文章信息
- 作者:雪候鸟 来源: 风雪之隅
- 标签: memory_limit 内存
- 发布时间:2009-11-27 18:16:11
建议继续学习
近3天十大热文
- [70] Twitter/微博客的学习摘要
- [66] 如何拿下简短的域名
- [65] IOS安全–浅谈关于IOS加固的几种方法
- [64] find命令的一点注意事项
- [63] android 开发入门
- [63] Go Reflect 性能
- [61] 流程管理与用户研究
- [59] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [59] 读书笔记-壹百度:百度十年千倍的29条法则