一次Out of memory 的 Fatal error

? ? ? ?有個(gè)寫的腳本是crontab每分鐘運(yùn)行一次的,后來發(fā)現(xiàn)腳本運(yùn)行有問題,于是查找log。log顯示腳本一分鐘運(yùn)行一次是沒問題的,但有時(shí)出現(xiàn)Fatal Error => Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)。

? ? ? ?瞬間認(rèn)為是memory_limit 參數(shù)的設(shè)置問題,于是果斷ini_set設(shè)置memory_limit為512M。提交后查看log,發(fā)現(xiàn)依舊有這個(gè)錯(cuò)誤。這就比較尷尬了,我回憶了下memory_limit的錯(cuò)誤提示,好像確實(shí)不是這個(gè),那就百度一下吧。

? ? ? ?經(jīng)過一陣百度,關(guān)于這個(gè)錯(cuò)誤有答案的回答都建議ini_set('limit_memory','1024M'),或者是在php.ini設(shè)置linit_memory重啟。那這就又尷尬了。。。。沒辦法,我只能

cd php-5.5.13/Zend; 
 grep "Out of memory" -R -n . 

定位到了zend_alloc.c的第1992行和第2304行。
第一個(gè)函數(shù)是 _zend_mm_alloc_int 第二個(gè)函數(shù)是 _zend_mm_realloc_int??疵诌@兩個(gè)函數(shù)是分配內(nèi)存的。接著定位到下面這一段。

//當(dāng)real_size (Zend 已經(jīng)分配的內(nèi)存大小) segment_size(這次要分配的segment的大小) 加起來大于 heap->limit
//報(bào) Allowed memory size 錯(cuò)誤,這里 heap->limit 參數(shù)就是設(shè)置的memory_limit
if (segment_size < true>real_size + segment_size > heap->limit) {
            /* Memory limit overflow */
#if ZEND_MM_CACHE
            zend_mm_free_cache(heap);
#endif
            HANDLE_UNBLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
            zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %lu bytes)", heap->li
mit, __zend_filename, __zend_lineno, size);
#else
            zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", heap->limit, size
);
#endif
        }

        segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);
        //這里當(dāng)上一步的 ZEND_MM_STORAGE_ALLOC失敗 會(huì)報(bào)Out of memory錯(cuò)誤
        //ZEND_MM_STORAGE_ALLOC宏 define ZEND_MM_STORAGE_ALLOC(size) heap->storage->handlers->_alloc(heap->storage, size)
        //storage在存儲(chǔ)層的操作,相關(guān)資料->看這里 http://www.phppan.com/2010/11/php-source-code-30-memory-pool-storage/
        //這里就是malloc啦 malloc失敗
        if (!segment) {
            /* Storage manager cannot allocate memory */
#if ZEND_MM_CACHE
            zend_mm_free_cache(heap);
#endif
out_of_memory:
            HANDLE_UNBLOCK_INTERRUPTIONS();
#if ZEND_DEBUG
            zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __ze
nd_filename, __zend_lineno, size);
#else
            zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
#endif
            return NULL;
        }

兩種錯(cuò)誤提示:

? ? ? ?1.當(dāng)segment_size < true>real_size + segment_size > heap->limit 時(shí), heap->limit就是memory_limit的值,如果要用的內(nèi)存比它大, 會(huì)報(bào)Allowed memory size of .....,

? ? ? ? 2.如果沒有超過設(shè)定的limit,接著ZEND_MM_STORAGE_REALLOC分配segment,當(dāng)!ZEND_MM_STORAGE_REALLOC(segment_copy, segment_size)時(shí),會(huì)報(bào)Out of memory。 分配失敗,報(bào)Out of memory錯(cuò)誤。

這里是malloc失敗,那么是不是服務(wù)器做了什么限制呢,我沒有權(quán)限登錄這臺(tái)服務(wù)器。于是發(fā)信去問,各種問過后發(fā)現(xiàn)是ulimit限制在125M。修改大后錯(cuò)誤消失。

一些參考

http://www.itdecent.cn/p/dd0013f28286

http://www.laruence.com/2011/11/09/2277.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 內(nèi)存是計(jì)算機(jī)非常關(guān)鍵的部件之一,是暫時(shí)存儲(chǔ)程序以及數(shù)據(jù)的空間,CPU只有有限的寄存器可以用于 存儲(chǔ)計(jì)算數(shù)據(jù),而大部...
    dreamer_lk閱讀 1,612評(píng)論 2 10
  • 關(guān)于PHP內(nèi)存管理的一些整理 背景故事 不知道大家是否還記得,我之前有聊過成立一個(gè)督促學(xué)習(xí)分享小組的設(shè)想,現(xiàn)在已經(jīng)...
    meng_philip123閱讀 1,715評(píng)論 0 4
  • 從西門進(jìn)入東大后左拐,穿越教學(xué)樓,在T字路口右轉(zhuǎn),再繼續(xù)走一段,便是和緩的上坡道,來到這里之后,即使閉著眼睛也可以...
    美美的睡一覺閱讀 284評(píng)論 0 2
  • 需要使用pip安裝,如果沒有安裝pip,請(qǐng)先安裝: 可以使用pip命令了,在終端里輸入 出現(xiàn)錯(cuò)誤fatal err...
    曉函閱讀 1,028評(píng)論 0 0
  • 又是一個(gè)細(xì)雨紛飛的下雨天, 我撐起一把白色的雨傘緩慢行走在雨幕里。 不是我喜歡漫步行走在潮濕的大路上, 而是有人曾...
    得我者幸閱讀 371評(píng)論 1 4

友情鏈接更多精彩內(nèi)容