2014-11-18 12 views
5

के साथ PHP मेमोरी त्रुटि मैं 2000x2000 (4 मिलियन प्रविष्टियों) के आकार के साथ PHP में 2 डी सरणी बनाने की कोशिश कर रहा हूं। ऐसा लगता है कि मैं यहां स्मृति से बाहर हूं, लेकिन जिस तरीके से त्रुटि दिखाई दे रही है वह मुझे भ्रमित कर रही है।बड़े ऐरे

जब मैं सरणी को परिभाषित करता हूं और इसे array_fill कमांड का उपयोग करके प्रारंभ में भरता हूं, और 0 के साथ सरणी (मैट्रिक्स) में प्रत्येक स्थिति को प्रारंभ करता है तो कोई समस्या नहीं होती है।

हालांकि अगर मैं सरणी पर फिर से प्रयास करने की कोशिश करता हूं और प्रत्येक स्थिति को 0 से भरता हूं, तो यह स्मृति से बाहर हो जाता है।

मुझे लगता है कि एक बार जब मैं array_fill चलाता हूं तो यह उस बिंदु पर स्मृति आवंटित करता है, और इसे लूप में स्मृति से बाहर नहीं होना चाहिए।

बेशक, यह कोड का एक सरलीकृत संस्करण है। मेरे वास्तविक एप्लिकेशन में मैं X & वाई का उपयोग अन्य तालिका से लुकअप वैल्यू के लिए निर्देशांक, प्रक्रिया को संसाधित करता हूं, और फिर इसे अपने मैट्रिक्स में संग्रहीत करता हूं। ये फ़्लोटिंग पॉइंट वैल्यू होंगे।

क्या कोई इस पर कुछ प्रकाश के माध्यम से मदद कर सकता है? क्या ऐसा कुछ और तरीका है जो मुझे करना चाहिए?

धन्यवाद!

<?php 

// Set error reporting. 
error_reporting(E_ALL); 
ini_set('display_errors', TRUE); 
ini_set('display_startup_errors', TRUE); 

// Define Matrix dimensions. 
define("MATRIX_WIDTH", 2000+1); 
define("MATRIX_HEIGHT", 2000+1); 


// Setup array for matrix and initialize it. 
$matrix = array_fill(0,MATRIX_HEIGHT,array_fill(0,MATRIX_WIDTH,0)); 

// Populate each matrix point with calculated value. 
for($y_cood=0;$y_cood<MATRIX_HEIGHT;$y_cood++) { 

    // Debugging statement to see where the script stops running. 
    if(($y_cood % 100) == 0) {print("Y=$y_cood<br>"); flush();} 

    for($x_cood=0;$x_cood<MATRIX_WIDTH;$x_cood++) { 
     $fill_value = 0; 
     $matrix[$y_cood][$x_cood]=$fill_value; 
    } 
} 

print("Matrix width: ".count($matrix)."<br>"); 
print("Matrix height: ".count($matrix[0])."<br>"); 

?> 
+0

PHP मेमोरी आकार 'memory_limit = 128M बढ़ाने की कोशिश करें; एक स्क्रिप्ट का उपभोग करने की अधिकतम मात्रा (128 एमबी) '। मैं व्यक्तिगत रूप से उन परिणामों पर विश्वास करने की सलाह नहीं देता जो अस्थिर स्क्रिप्ट व्यवहार के कारण होते हैं। –

+0

धन्यवाद। क्या वह अंततः था। –

उत्तर

4

मुझे लगता है कि यह उस बिंदु पर स्मृति आवंटित करता है एक बार मैं array_fill चलाने के लिए, और यह पाश में स्मृति से बाहर चलाने के नहीं करना चाहिए।

हाँ ... और नहीं। स्मृति आवंटित करना और प्रोग्राम कोड निष्पादित करना दो अलग-अलग जूते (आमतौर पर) होते हैं।
किसी प्रोग्राम/प्रक्रिया को आवंटित स्मृति आमतौर पर दो - ढेर और ढेर में विभाजित होती है। जब आप "स्मृति आवंटित करें" (जिसका मतलब आपने अपने प्रश्न में उपयोग किया था), यह ढेर में होता है। जब आप प्रोग्राम कोड निष्पादित करते हैं, तो स्टैक का भी उपयोग किया जाता है। दोनों पूरी तरह से अलग नहीं होते हैं, क्योंकि आप स्टैक पर और/या से संदर्भों को धक्का और/या पॉप (ढेर पर पॉइंटर्स) पॉप कर सकते हैं।

बात यह है कि ढेर और ढेर मेमोरी (उस प्रक्रिया को आवंटित) का हिस्सा साझा करते हैं और आमतौर पर एक को उच्च पते से कम (दूसरे में भर दिया जाता है) और कम पते से कम पते तक एक उच्च, और इसलिए आपके बीच दोनों "फ़्लोटिंग" सीमा है। जैसे ही दोनों भाग उस "सीमा" तक पहुंच जाते हैं, आप "स्मृति से बाहर" होते हैं।
enter image description here

तो, आपके मामले में, जब आप बनाते हैं और अपने सरणी (मैट्रिक्स) को भरने के आप स्मृति 2001 X 2001 पूर्णांकों के लिए उपयोग किया है। यदि एक पूर्णांक के लिए 32 बिट्स या 4 बाइट्स की आवश्यकता होती है, तो 2001 x 2001 x 4 बाइट्स = 4004001 x 4 बाइट्स = 16016004 बाइट्स ~ 16 एमबी हैं।
कोड निष्पादित करते समय, स्टैक को (स्थानीय) चर से भरा जा रहा है - लूप स्थिति चर, लूप काउंटर और अन्य सभी चर।
आपको यह भी नहीं भूलना चाहिए कि PHP (लाइब्रेरी) कोड को स्मृति में भी लोड किया जाना चाहिए, इसलिए आपके कॉन्फ़िगरेशन में memory_limit के रूप में सेट किए गए मान के आधार पर, आप जल्दी से स्मृति से बाहर हो सकते हैं।

+1

स्पष्टीकरण के लिए धन्यवाद! –