ข้อผิดพลาดร้ายแรง: ขนาดหน่วยความจำที่อนุญาตของ 134217728 ไบต์หมดลง (CodeIgniter + XML-RPC)


618

ฉันมีระบบจุดขายลูกค้า (POS) มากมายที่ส่งข้อมูลการขายใหม่เป็นระยะ ๆ ไปยังฐานข้อมูลส่วนกลางหนึ่งฐานซึ่งจัดเก็บข้อมูลไว้ในฐานข้อมูลขนาดใหญ่หนึ่งฐานสำหรับการสร้างรายงาน

POS ของลูกค้าขึ้นอยู่กับ PHPPOS และฉันได้ติดตั้งโมดูลที่ใช้ไลบรารี XML-RPC มาตรฐานเพื่อส่งข้อมูลการขายไปยังบริการ ระบบเซิร์ฟเวอร์ถูกสร้างขึ้นบน CodeIgniter และใช้ไลบรารี XML-RPC และ XML-RPCS สำหรับคอมโพเนนต์เว็บเซอร์ เมื่อใดก็ตามที่ฉันส่งข้อมูลการขายจำนวนมาก (อย่างน้อย 50 แถวจากตารางการขายและแต่ละแถวจาก sales_items ที่เกี่ยวข้องกับแต่ละรายการภายในการขาย) ฉันได้รับข้อผิดพลาดดังต่อไปนี้:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 54 bytes)

128M เป็นค่าเริ่มต้นphp.iniแต่ฉันคิดว่านั่นเป็นจำนวนมากที่จะทำลาย ในความเป็นจริงฉันได้ลองตั้งค่านี้เป็น 1024M และทั้งหมดใช้เวลานานในการผิดพลาด

สำหรับขั้นตอนที่ฉันทำฉันได้ลองปิดการใช้งานการประมวลผลทั้งหมดที่ฝั่งเซิร์ฟเวอร์และได้ทำการทดสอบเพื่อส่งคืนการตอบกลับสำเร็จรูปโดยไม่คำนึงถึงอินพุต อย่างไรก็ตามฉันเชื่อว่าปัญหาอยู่ที่การส่งข้อมูลจริง ฉันได้ลองปิดการใช้งานสคริปต์เวลาสูงสุดสำหรับ PHP และยังคงมีข้อผิดพลาดอยู่


5
ฉันสับสนเล็กน้อย ... เกิดข้อผิดพลาดที่ใดในไคลเอนต์หรือเซิร์ฟเวอร์ และในขั้นตอนใด ... การส่งไคลเอ็นต์การรับเซิร์ฟเวอร์การประมวลผลเซิร์ฟเวอร์การส่งเซิร์ฟเวอร์การรับไคลเอ็นต์หรือการประมวลผลไคลเอ็นต์
เกร็ก

2
ดูเหมือนว่าข้อผิดพลาดจะเกิดขึ้นในระหว่างการส่งไคลเอ็นต์หรือเซิร์ฟเวอร์ที่ได้รับ ฉันได้ลองปิดการใช้งานการประมวลผลทั้งหมดของเซิร์ฟเวอร์และทำการส่งการตอบกลับสำเร็จรูปโดยไม่คำนึงถึงข้อมูลที่ส่ง ข้อผิดพลาดเกิดขึ้นหากฉันส่งข้อมูลจำนวนหนึ่ง ฉันกำลังเปลี่ยนการตั้งค่า PHP.ini
ArcticZero

42
ขีด จำกัด หน่วยความจำคือ 128MB หน่วยความจำสองเท่า:ini_set('memory_limit', '256M');

9
สรุปลงคะแนนทั้งหมดคำตอบ "เพียงแค่ละเว้นการรั่วไหล" คนที่สับสน CodeIgniter กับ Drupal และคนที่เพิ่งคัดลอกและวางคำตอบของคนอื่นเพื่อรับคะแนน คุณภาพของคำตอบในอันนี้คือสุดยอด
Matti Virkkunen

คำตอบ:


697

การเปลี่ยน memory_limitจากini_set('memory_limit', '-1');เป็นไม่ได้วิธีที่เหมาะสม โปรดอย่าทำอย่างนั้น

รหัส PHP ของคุณอาจมีหน่วยความจำรั่วที่ใดที่หนึ่งและคุณกำลังบอกเซิร์ฟเวอร์ให้ใช้หน่วยความจำทั้งหมดที่ต้องการ คุณจะไม่ได้แก้ไขปัญหาเลย หากคุณตรวจสอบเซิร์ฟเวอร์ของคุณคุณจะเห็นว่าตอนนี้อาจใช้ RAM เกือบทั้งหมดและยังเปลี่ยนเป็นดิสก์

คุณอาจลองติดตามรหัสที่ละเมิดในรหัสของคุณและแก้ไข


173
@ เจฟฟ์คุณอาจถูก 95% ของเวลา อย่างไรก็ตามมีบางครั้งที่คุณต้องการหน่วยความจำมากขึ้น ตัวอย่างเช่นสมมติว่าแอปของคุณโหลดข้อมูลจำนวนมากลงในหน่วยความจำเพื่อการประมวลผล (พูดว่า Bill of Material พร้อมส่วนประกอบ 15k) บางครั้งคุณอาจต้องการหน่วยความจำเพิ่มขึ้นเล็กน้อย (เช่น 256M แทนที่จะเป็น 128M) อย่างไรก็ตามฉันยอมรับว่าการตั้งค่าเป็น -1 นั้นแย่มาก แต่การปรับขีด จำกัด หน่วยความจำสำหรับสถานการณ์ที่เหมาะสมในเวลาทำงานนั้นเป็นที่ยอมรับอย่างสมบูรณ์
Pyrite

24
@pyrite ใช่คุณถูกที่บางครั้งกระบวนการต้องการหน่วยความจำเพิ่ม แต่คุณควรเพิ่มจำนวนหน่วยความจำให้เท่ากับจำนวนโลจิคัลเช่น 256MB ตามที่คุณพูดหรือ 512MB ทำไมไม่ แต่ไม่ใช่ -1;)
Lukas Lukac

9
@jeff ฉันเห็นด้วยอย่างเต็มที่ค่า-1อาจมีประโยชน์เฉพาะในสภาพแวดล้อม dev เพื่อทดสอบวัตถุประสงค์
Esolitos

4
@Prite ในกรณีที่คุณตั้งชื่อให้ส่วนที่เหลืออีก 5% อ่านข้อมูลเป็นกลุ่มและใช้คนงานเพื่อดำเนินการแทนการใช้หน่วยความจำเพิ่มเติม โซลูชันนี้จะขยายขนาดเช่นกันในขณะที่ข้อเสนอแนะของคุณจะไม่ทำงานยกเว้นคุณจะเก็บหน่วยความจำในเซิร์ฟเวอร์ของคุณมากขึ้นเรื่อย ๆ ตลอดเวลาหากข้อมูลเติบโตขึ้น
burzum

2
โดยทั่วไปปัญหานี้ใน ORM เมื่อคุณพยายามที่จะดึงข้อมูลทั้งหมดที่ จำกัด หน่วยความจำ php มากขึ้น ตัวอย่างเช่นเมื่อคุณพยายามสร้างรายงานรายเดือน
Stepchik

213

ini_set('memory_limit', '-1');แทนที่เริ่มต้นความจำสูงสุด PHP


16
@williamcarswell; -1เป็นค่า PHP ที่เข้าใจได้ไม่ จำกัดในบริบทนี้
Alix Axel

7
@ ArseniuszŁozicki - มันจะใช้ทรัพยากรที่เซิร์ฟเวอร์ไม่สามารถสำรองได้
Ken Williams

124
อัปยศที่นี้ได้รับ upvotes มากมาย การตั้งค่าให้เป็นค่าที่ถูกต้องด้วยการแก้ไข php.ini หรือ ini_set เป็นโซลูชันที่ถูกต้องสมบูรณ์แบบเมื่อผู้คนต้องการหน่วยความจำมากขึ้น การแฮ็กมันอันตราย :(
Jeff Davis

24
@ user1767586 จากนั้นตั้งเป็นค่าสติ คุณสามารถป้องกันสคริปต์จากการโยนข้อผิดพลาดโดยการตั้งค่าเป็น 1024M หากคำตอบนี้พูด ini_set ('memory_limit', '1024M'); คุณสามารถคัดลอกและวางได้ โดยการตั้งค่าเป็น -1 คุณกำลังตั้งค่าตัวเองให้มีสคริปต์ที่ใช้หน่วยความจำทั้งหมด โดยเฉพาะถ้าคุณทำสิ่งนี้เป็นประจำ การใส่ "อันตราย" ไว้ในเครื่องหมายคำพูดไม่ได้ทำให้อันตรายน้อยลง คุณสามารถโฮสต์เซิร์ฟเวอร์โฮสต์ของคุณได้จริงๆ อาจเริ่มทำลายข้อมูล ฉันไม่รู้อาจจะสูญเสียงานของคุณ? ฟังดูค่อนข้างอันตรายสำหรับฉัน : |
Jeff Davis

3
น่าเศร้าที่เห็นว่าคำตอบสำหรับ +161 โหวตและ -3 โหวตเหมือนกัน :(
akarthik10

130

วิธีที่ถูกต้องคือแก้ไขphp.iniไฟล์ของคุณ แก้ไขmemory_limitค่าความปรารถนาของคุณ

จากคำถามของคุณ128Mเกินขีด จำกัด เริ่มต้นแล้วดังนั้นจึงมีบางอย่างผิดปกติกับรหัสของคุณเนื่องจากไม่ควรใช้มาก

หากคุณรู้ว่าทำไมมันถึงต้องใช้จำนวนมากและคุณต้องการอนุญาตให้ตั้งค่าmemory_limit = 512Mหรือสูงกว่าและคุณควรจะดี


7
สุจริตถ้าคุณแคชข้อมูลจำนวนร้ายแรงนี่คือคำตอบที่ถูกต้อง 128M ไม่เพียงพอสำหรับสคริปต์บางตัว 512M หรือ 1024M มักจะเพียงพอ แต่คุณต้องตัดสินใจเป็นกรณีไป
Jeff Davis

2
Yeha แต่พยายามที่จะหลีกเลี่ยงการใช้หน่วยความจำขนาดใหญ่ถ้าจำนวนผู้ใช้ที่เป็นไปได้มากขึ้น
Basav

2
memory_limit = -1; ตั้งใน php.ini

2
@YumYumYum ที่ลบ memory_limit ซึ่งคุณต้องการหากคุณกำลังตรวจสอบการใช้หน่วยความจำด้วยวิธีอื่น ระบบปฏิบัติการจะฆ่ากระบวนการหากใช้หน่วยความจำจำนวนมากในบางจุด
Flimm

ดังนั้นหากคุณกำลังเรียกใช้สคริปต์ที่ใช้หน่วยความจำจำนวนมาก แต่คุณจะต้องเรียกใช้เพียงครั้งเดียวคุณสามารถเพิ่มขีด จำกัด หน่วยความจำสำหรับกระบวนการในช่วงเวลาของการดำเนินการแล้วลดขีด จำกัด หน่วยความจำของคุณอีกครั้งหลังจากครั้งเดียว สคริปต์ทำงานหรือไม่
chromechris

95

การจัดสรรหน่วยความจำสำหรับ PHP สามารถปรับได้อย่างถาวรหรือชั่วคราว

อย่างถาวร

คุณสามารถเปลี่ยนการจัดสรรหน่วยความจำ PHP อย่างถาวรได้สองวิธี

หากคุณสามารถเข้าถึงphp.iniไฟล์ของคุณคุณสามารถแก้ไขค่าสำหรับmemory_limitค่าความปรารถนาของคุณ

หากคุณไม่สามารถเข้าถึงphp.iniไฟล์ของคุณ(และโฮสต์ของคุณอนุญาต) คุณสามารถแทนที่การจัดสรรหน่วยความจำผ่าน.htaccessไฟล์ของคุณ เพิ่มphp_value memory_limit 128M(หรือการจัดสรรที่คุณต้องการ)

ชั่วคราว

คุณสามารถปรับการจัดสรรหน่วยความจำได้ทันทีจากภายในไฟล์ PHP คุณมีรหัสini_set('memory_limit', '128M');(หรือสิ่งที่คุณต้องการจัดสรร) คุณสามารถลบขีด จำกัด หน่วยความจำ (แม้ว่าเครื่องหรืออินสแตนซ์ข้อ จำกัด อาจยังคงใช้) โดยการตั้งค่าเป็น "-1"


2
ขอบคุณฉันไม่คิดว่าจะตรวจสอบว่ามีใครบางคนตั้งค่าเป็น. htaccess ซึ่งแทนที่ php.ini และฉันคิดไม่ออกว่าทำไม +1
HostMyBus

61

มันง่ายมากที่จะทำให้หน่วยความจำรั่วในสคริปต์ PHP โดยเฉพาะอย่างยิ่งถ้าคุณใช้สิ่งที่เป็นนามธรรมเช่น ORM ลองใช้ Xdebug เพื่อสร้างโปรไฟล์สคริปต์ของคุณและค้นหาว่าหน่วยความจำนั้นไปที่ใด


1
ฉันจะไปลอง Xdebug ฉันไม่เคยใช้มันมาก่อนดังนั้นฉันจะต้องอ่านมันก่อน ขอบคุณสำหรับการตอบกลับ! หวังว่าฉันจะหาคำตอบสำหรับเรื่องนี้ในไม่ช้า ...
ArcticZero

34
จำไว้ว่า PHP ใช้การนับการอ้างอิงเพื่อจัดการหน่วยความจำ ดังนั้นหากคุณมีการอ้างอิงแบบวงกลมหรือตัวแปรทั่วโลกวัตถุเหล่านั้นจะไม่ได้รับการรีไซเคิล นั่นคือรากของหน่วยความจำรั่วใน PHP
troelskn

Xdebug แสดงให้เห็นว่าห้องสมุด Xmlrpc.php ของ CI รับผิดชอบการรั่วไหลของหน่วยความจำของฉัน มีโอกาสเกิดอะไรขึ้นกับห้องสมุด XML-RPC ของ CodeIgniter ที่ฉันควรรู้ ฉันได้ลองปิดการใช้งานการประมวลผลฝั่งเซิร์ฟเวอร์ทั้งหมดและยังคงมีหน่วยความจำไม่เพียงพอหากฉันป้อนข้อมูลให้เพียงพอ
ArcticZero

1
ฉันไม่รู้ / ใช้ CI ดังนั้นฉันไม่รู้ แต่คุณควรพยายามหาวัตถุที่ไม่ได้รับการปลดปล่อยหลังจากการใช้งานซึ่งน่าจะเป็นเพราะการอ้างอิงแบบวงกลม มันเป็นงานนักสืบ
troelskn

1
นี่เป็นคำตอบเดียวที่นี่ที่ให้คำแนะนำแก้ไขปัญหาได้อย่างแท้จริง คำตอบอื่น ๆ เหวี่ยงขึ้นหน่วยความจำเพื่อผ้าพันแผลมากกว่าอาการและไม่สนใจโรค
คริสเบเกอร์

56

เมื่อเพิ่ม 22.5 ล้านบันทึกลงในอาร์เรย์ด้วย array_push ฉันยังคงได้รับข้อผิดพลาดร้ายแรง "หน่วยความจำหมด" ที่ประมาณ 20 ล้านระเบียนโดยใช้4Gเป็นขีด จำกัด หน่วยความจำในไฟล์ php.ini เพื่อแก้ไขปัญหานี้ฉันได้เพิ่มคำสั่ง

$old = ini_set('memory_limit', '8192M');

ที่ด้านบนของไฟล์ ตอนนี้ทุกอย่างทำงานได้ดี ฉันไม่รู้ว่า PHP มีหน่วยความจำรั่วหรือไม่ นั่นไม่ใช่งานของฉันและฉันไม่สนใจ ฉันต้องทำงานให้เสร็จและสิ่งนี้ใช้ได้ผล

โปรแกรมง่ายมาก:

$fh = fopen($myfile);
while (!feof($fh)) {
    array_push($file, stripslashes(fgets($fh)));
}
fclose($fh);

ข้อผิดพลาดร้ายแรงชี้ไปที่บรรทัดที่ 3 จนกว่าฉันจะเพิ่มขีด จำกัด หน่วยความจำซึ่งกำจัดข้อผิดพลาด


10
คุณหมายถึงini_set('memory_limit', '8192M');อะไร
โกกอล

2
ช่างเป็นอะไรที่หรูหราที่จะมีเวลาไปและปรับสคริปต์ให้เหมาะสมสำหรับสิ่งนั้น หรือค้นคว้าและเปรียบเทียบและเรียนรู้เครื่องมือ ETL หรือบางอย่าง ในโลกแห่งความเป็นจริงเราจะเพิ่มหน่วยความจำให้มากขึ้นทำสิ่งนั้นและเดินหน้าต่อไป
Matthew Poer

45

ฉันยังคงได้รับข้อผิดพลาดนี้แม้จะmemory_limitตั้งค่าphp.iniแล้วและอ่านค่าได้อย่างถูกต้องด้วยphpinfo()และค่าที่อ่านออกมาได้อย่างถูกต้องด้วย

ด้วยการเปลี่ยนจากสิ่งนี้:

memory_limit=4G

สำหรับสิ่งนี้:

memory_limit=4096M

วิธีนี้แก้ไขปัญหาใน PHP 7


23

เมื่อคุณเห็นข้อผิดพลาดด้านบน - โดยเฉพาะอย่างยิ่งถ้า(tried to allocate __ bytes)เป็นค่าต่ำนั่นอาจเป็นตัวบ่งชี้ของการวนซ้ำไม่สิ้นสุดเช่นฟังก์ชันที่เรียกตัวเองว่าไม่มีทางออก:

function exhaustYourBytes()
{
    return exhaustYourBytes();
}

19

หลังจากเปิดใช้งานทั้งสองบรรทัดแล้วจะเริ่มทำงาน:

; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; http://php.net/realpath-cache-size
realpath_cache_size = 16k

; Duration of time, in seconds for which to cache realpath information for a given
; file or directory. For systems with rarely changing files, consider increasing this
; value.
; http://php.net/realpath-cache-ttl
realpath_cache_ttl = 120


19

คุณสามารถแก้ไขได้โดยเปลี่ยนmemory_limitfastcgi / fpm:

$vim /etc/php5/fpm/php.ini

เปลี่ยนหน่วยความจำเช่นจาก 128 เป็น 512 ดูด้านล่าง

; Maximum amount of memory a script may consume (128 MB)
; http://php.net/memory-limit
memory_limit = 128M

ถึง

; Maximum amount of memory a script may consume (128 MB)
; http://php.net/memory-limit
memory_limit = 512M

18

ไดเรกทอรีรากของเว็บไซต์ของคุณ:

ini_set('memory_limit', '1024M');

1
สิ่งนี้ใช้ได้สำหรับฉัน รักโซลูชั่นบรรทัดเดียว +1 เพื่อความง่าย
Steve C

14

เปลี่ยนขีด จำกัด หน่วยความจำในไฟล์ php.iniและรีสตาร์ท Apache หลังจากรีสตาร์ทให้เรียกใช้phpinfo (); ฟังก์ชั่นจากไฟล์ PHP ใด ๆ สำหรับmemory_limitการยืนยันการเปลี่ยนแปลง

memory_limit = -1

ขีด จำกัด หน่วยความจำ -1 หมายถึงไม่มีการตั้งค่าขีด จำกัด หน่วยความจำ เป็นจำนวนสูงสุดแล้ว


13

สำหรับผู้ใช้ Drupal คำตอบของ Chris Lane จาก:

ini_set('memory_limit', '-1');

ใช้งานได้ แต่เราต้องวางมันหลังจากการเปิด

<?php

แท็กในไฟล์ index.php ในไดเรกทอรีรากของเว็บไซต์ของคุณ


13

ใน Drupal 7 คุณสามารถแก้ไขขีด จำกัด หน่วยความจำในไฟล์ settings.php ที่อยู่ในไซต์ / โฟลเดอร์เริ่มต้นของคุณ ประมาณบรรทัดที่ 260 คุณจะเห็นสิ่งนี้:

ini_set('memory_limit', '128M');

แม้ว่าการตั้งค่า php.ini ของคุณจะสูงพอคุณจะไม่สามารถกินได้มากกว่า 128 MB หากไม่ได้ตั้งค่าไว้ในไฟล์ Drupal settings.php


1
ไม่ได้อยู่ใน Drupal7 ไม่มีสตริงของรหัสดังกล่าวใน settings.php
FLY

นอกจากนี้ยังไม่มีสตริงใน settings.php สำหรับ drupal 6
AllisonC

12

แทนที่จะเปลี่ยนmemory_limitค่าในphp.iniไฟล์ของคุณหากมีส่วนหนึ่งของรหัสของคุณที่สามารถใช้หน่วยความจำได้จำนวนมากคุณสามารถลบส่วนmemory_limitก่อนที่ส่วนนั้นจะทำงานแล้วแทนที่หลังจากนั้น

$limit = ini_get('memory_limit');
ini_set('memory_limit', -1);
// ... do heavy stuff
ini_set('memory_limit', $limit);

7

PHP 5.3+ ช่วยให้คุณสามารถเปลี่ยนขีด จำกัด หน่วยความจำโดยการวาง.user.iniไฟล์ในpublic_htmlโฟลเดอร์ เพียงสร้างไฟล์ด้านบนแล้วพิมพ์บรรทัดต่อไปนี้ลงไป:

memory_limit = 64M

โฮสต์ cPanel บางคนยอมรับวิธีนี้เท่านั้น


7

หน้าผิดพลาดหรือไม่

ป้อนคำอธิบายภาพที่นี่

(มันเกิดขึ้นเมื่อ MySQL ต้องสืบค้นแถวขนาดใหญ่โดยค่าเริ่มต้นmemory_limitจะถูกตั้งค่าเป็นขนาดเล็กซึ่งปลอดภัยสำหรับฮาร์ดแวร์)

คุณสามารถตรวจสอบสถานะหน่วยความจำที่มีอยู่ในระบบก่อนเพิ่มphp.ini:

# free -m
             total       used       free     shared    buffers     cached
Mem:         64457      63791        666          0       1118      18273
-/+ buffers/cache:      44398      20058
Swap:         1021          0       1021

ที่นี่ฉันได้เพิ่มขึ้นดังต่อไปนี้แล้วทำservice httpd restartเพื่อแก้ไขปัญหาหน้าผิดพลาด

# grep memory_limit /etc/php.ini
memory_limit = 512M

หมายเลขใด (แถวและคอลัมน์) ที่ควรดูหลังจากใช้free -mคำสั่งเพื่อตัดสินใจเกี่ยวกับ memory_limit ใหม่
kiradotee

7

เพียงเพิ่มini_set('memory_limit', '-1');บรรทัดที่ด้านบนของหน้าเว็บของคุณ

และคุณสามารถตั้งค่าหน่วยความจำของคุณตามความต้องการของคุณในสถานที่ของ -1, ถึง16M, ฯลฯ


6
สิ่งนี้ดูเหมือนจะพูดในสิ่งเดียวกันกับคำตอบที่มีอยู่มากมาย เป็นการดีที่สุดที่จะเพิ่มคำตอบสำหรับคำถามยอดนิยมเฉพาะในกรณีที่เนื้อหาใหม่นำเสนอสิ่งใหม่
halfer

6

สำหรับผู้ที่เกาหัวเพื่อค้นหาว่าทำไมในโลกนี้ฟังก์ชั่นเล็ก ๆ น้อย ๆ ควรทำให้เกิดความจำรั่วบางครั้งก็เกิดความผิดพลาดเล็กน้อย

ตัวอย่างเช่นคลาสพร็อกซีที่มีชื่อเดียวกันสำหรับฟังก์ชั่นของวัตถุที่กำลังจะใช้พร็อกซี

class Proxy {

    private $actualObject;

    public function doSomething() {

        return $this->actualObjec->doSomething();
    }
}

บางครั้งคุณอาจลืมที่จะนำสมาชิกจริงของ Ojjec ตัวน้อยและเนื่องจากพร็อกซีมีdoSomethingวิธีการดังกล่าวจริง ๆ แล้วPHP จะไม่ให้ข้อผิดพลาดใด ๆ แก่คุณและสำหรับชั้นเรียนขนาดใหญ่ กำลังรั่วหน่วยความจำ


และเคล็ดลับอื่น: คุณสามารถใส่die('here')รหัสของคุณและย้ายคำสั่งนั้นไปรอบ ๆ เพื่อดูว่าการเรียกซ้ำเกิดขึ้นที่ไหน
toddmo

6

ฉันมีข้อผิดพลาดด้านล่างขณะที่ทำงานบนชุดข้อมูลที่เล็กกว่าที่เคยทำงานก่อนหน้านี้

ข้อผิดพลาดร้ายแรง: ขนาดหน่วยความจำที่อนุญาตคือ 134217728 ไบต์หมดลง (พยายามจัดสรร 4096 ไบต์) ใน C: \ workspace \ image_management.php ที่บรรทัด 173

เมื่อการค้นหาข้อผิดพลาดทำให้ฉันมาที่นี่ฉันคิดว่าฉันพูดถึงว่ามันไม่ใช่คำตอบทางเทคนิคในคำตอบก่อนหน้านี้เสมอไป แต่เป็นเรื่องที่ง่ายขึ้น ในกรณีของฉันมันคือ Firefox ก่อนที่ฉันจะรันโปรแกรมมันใช้งานไปแล้ว 1,157 MB

ปรากฎว่าฉันได้รับชมวิดีโอ 50 นาทีในช่วงระยะเวลาหนึ่งวันและสิ่งที่เกิดขึ้นยุ่งเหยิง มันเป็นประเภทของการแก้ไขที่ผู้เชี่ยวชาญแก้ไขได้โดยไม่ต้องคิดถึงมัน แต่สำหรับคนที่ชอบฉันมันก็คุ้มค่าที่จะนึกถึง


วันนี้ฉันมีสิ่งที่คล้ายกันใน Google Chrome ฉันสงสัยอย่างมากต่อคำตอบนี้ ... แต่มันเผยให้เห็นว่าความเหนื่อยล้าของฉันหายไปหลังจากที่ฉันเปิดหน้าต่างที่ไม่ระบุตัวตนและยิงสคริปต์เดิมอีกครั้ง! การวิจัยอย่างต่อเนื่อง
mickmackusa

2

ใช้สคริปต์เช่นนี้ (ตัวอย่างเช่น cron): php5 /pathToScript/info.phpสร้างข้อผิดพลาดเดียวกัน

วิธีที่ถูกต้อง: php5 -cli /pathToScript/info.php


2

หากคุณใช้ VPS ที่ขับเคลื่อนโดย WHM (เซิร์ฟเวอร์ส่วนตัวเสมือน) คุณอาจพบว่าคุณไม่มีสิทธิ์แก้ไข PHP.INI โดยตรง ระบบต้องทำ ในแผงควบคุมโฮสต์ WHM ไปที่Service ConfigurationPHP Configuration Editorและแก้ไขmemory_limit:

กำลังอัปเดต memory_limit ใน WHM 11.48.4


2

ฉันพบว่ามีประโยชน์เมื่อรวมหรือต้องการ_dbconnection.php_และ_functions.phpในไฟล์ที่ประมวลผลจริงแทนที่จะรวมไว้ในส่วนหัว ซึ่งรวมอยู่ในตัวของมันเอง

ดังนั้นหากส่วนหัวและส่วนท้ายของคุณรวมอยู่ด้วยเพียงแค่รวมไฟล์การทำงานทั้งหมดของคุณก่อนที่จะรวมส่วนหัว


2

การใช้yieldอาจเป็นวิธีแก้ปัญหาเช่นกัน ดูไวยากรณ์ของตัวสร้าง

แทนที่จะเปลี่ยนPHP.iniไฟล์สำหรับหน่วยความจำขนาดใหญ่บางครั้งการใช้yieldวงในอาจช่วยแก้ไขปัญหาได้ สิ่งที่ได้ผลคือแทนที่จะทิ้งข้อมูลทั้งหมดในครั้งเดียวมันอ่านทีละตัวเพื่อประหยัดการใช้หน่วยความจำจำนวนมาก


2
PHP.ini? ไม่ใช่php.iniเหรอ
Peter Mortensen

1

ข้อผิดพลาดนี้บางครั้งเกิดจากข้อผิดพลาดในรหัส PHP ที่ทำให้เกิดการสอบถามซ้ำที่เกี่ยวข้องกับการจัดการข้อยกเว้นและการดำเนินการอื่น ๆ ที่อาจเกิดขึ้น น่าเสียดายที่ฉันไม่สามารถสร้างตัวอย่างเล็ก ๆ ได้

ในกรณีเหล่านี้ซึ่งเกิดขึ้นกับฉันหลายครั้ง set_time_limitล้มเหลวและเบราว์เซอร์พยายามโหลดเอาต์พุต PHP ทั้งที่มีลูปไม่สิ้นสุดหรือมีข้อความแสดงข้อผิดพลาดร้ายแรงซึ่งเป็นหัวข้อของคำถามนี้

โดยการลดขนาดการจัดสรรที่อนุญาตโดยการเพิ่ม

ini_set('memory_limit','1M');

ใกล้ถึงจุดเริ่มต้นของรหัสของคุณคุณควรจะสามารถป้องกันข้อผิดพลาดร้ายแรงได้

จากนั้นคุณอาจถูกทิ้งให้อยู่กับโปรแกรมที่ยกเลิก แต่ก็ยังยากที่จะทำการดีบัก

ณ จุดนี้แทรกการBreakLoop()โทรภายในโปรแกรมของคุณเพื่อรับการควบคุมและค้นหาว่าลูปหรือการเรียกซ้ำในโปรแกรมของคุณก่อให้เกิดปัญหา

คำจำกัดความของ BreakLoop มีดังนี้:

function BreakLoop($MaxRepetitions=500,$LoopSite="unspecified")
    {
    static $Sites=[];
    if (!@$Sites[$LoopSite] || !$MaxRepetitions)
        $Sites[$LoopSite]=['n'=>0, 'if'=>0];
    if (!$MaxRepetitions)
        return;
    if (++$Sites[$LoopSite]['n'] >= $MaxRepetitions)
        {
        $S=debug_backtrace(); // array_reverse
        $info=$S[0];
        $File=$info['file'];
        $Line=$info['line'];
        exit("*** Loop for site $LoopSite was interrupted after $MaxRepetitions repetitions. In file $File at line $Line.");
        }
    } // BreakLoop

อาร์กิวเมนต์ $ LoopSite สามารถเป็นชื่อของฟังก์ชันในรหัสของคุณ ไม่จำเป็นจริงๆเนื่องจากข้อความแสดงข้อผิดพลาดที่คุณจะได้รับจะนำคุณไปยังบรรทัดที่มีการโทร BreakLoop ()


-1

ในกรณีของฉันมันเป็นปัญหาสั้น ๆ เกี่ยวกับวิธีการเขียนฟังก์ชั่น การรั่วไหลของหน่วยความจำอาจเกิดจากการกำหนดค่าใหม่ให้กับตัวแปรอินพุตของฟังก์ชันเช่น:

/**
* Memory leak function that illustrates unintentional bad code
* @param $variable - input function that will be assigned a new value
* @return null
**/
function doSomehting($variable){
    $variable = 'set value';
    // Or
    $variable .= 'set value';
}

-6

เมื่อฉันลบบรรทัดต่อไปนี้ออกจากรหัสของฉันทำงานได้ดี

set_include_path(get_include_path() . get_include_path() . '/phpseclib');
include_once('Net/SSH2.php');
include_once('Net/SFTP.php');

บรรทัดเหล่านี้รวมอยู่ในไฟล์ทุกไฟล์ที่ฉันใช้ เมื่อเรียกใช้ไฟล์ทีละรายการทำงานได้ดี แต่เมื่อใช้งานไฟล์ทั้งหมดร่วมกันฉันได้รับปัญหาหน่วยความจำรั่ว ยังไงก็เถอะ "include_once" ไม่ได้รวมสิ่งต่าง ๆ เพียงครั้งเดียวหรือฉันกำลังทำอะไรผิดไป ...


set_include_path(get_include_path() . get_include_path().'/phpseclib'); นี่จะเพิ่มพา ธ '/ phpseclib' หนึ่งครั้งสำหรับแต่ละไฟล์ที่มีบรรทัด ... เพื่อให้สามารถเพิ่มได้หลายครั้ง! ฉันขอแนะนำให้วางไว้ในไฟล์การตั้งค่าและไฟล์include_onceการตั้งค่า
Farfromunique
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.