2013-03-25 13 views
8

मैं अपने विंडोज आधारित सॉफ़्टवेयर में 4 लाख त्रिकोण प्रस्तुत करना चाहता हूं जो विजुअल स्टूडियो सी ++ 2010 (रिलीज मोड में निर्मित) में लिखा गया है। जब मैं 3.9 मिलियन त्रिकोण प्रस्तुत करता हूं, तो सॉफ्टवेयर द्वारा खपत कुल रैम मेमोरी 400 एमबी है। लेकिन जब मैं 4 लाख त्रिकोण (केवल 100K अधिक) प्रस्तुत करने का प्रयास करता हूं, तो सिस्टम मुझे एक त्रुटि देता है।मैं अपने आवेदन के लिए विजुअल स्टूडियो में सभी उपलब्ध स्मृति कैसे आवंटित कर सकता हूं?

For Example: 
Point *P = new (std::nothrow) Point[nb_triangles]; //==> "(std::nothrow)" is for catching the run time memory allocation error. (Point is X, Y, Z floats) 
If(P == NULL) 
    message("System can't allocate this much memory."); // System gives me this error. It means the system can't reserve huge memory for this operation. 

मैं आदि कोने, चेहरा Normals, शिखर normals के लिए स्मृति,

असल में आवंटित करने के लिए है कि मैं क्या नहीं मिल रहा है कर रहा है, मेरे पास 8 जीबी रैम मेमोरी, (लेकिन 32 बिट XP खिड़कियों में = 3.2 जीबी मेमोरी), और सॉफ्टवेयर सिर्फ 400 एमबी आरक्षित है, मुफ्त मेमोरी 1 जीबी से अधिक है, लेकिन जब मैं केवल 100 के त्रिकोणों को प्रस्तुत करने की कोशिश करता हूं, तो यह मुझे एक त्रुटि देता है। यह मुझे एक त्रुटि क्यों दे रहा है? क्योंकि इसमें अभी भी 1 जीबी से अधिक रैम मेमोरी है?

क्या इस समस्या को ठीक करने के लिए वैसे भी है, मैं अपने आवेदन के लिए सभी उपलब्ध स्मृति आवंटित कैसे कर सकता हूं? इस समस्या के कारण, मुझे केवल 3.9 लाख त्रिकोणों को प्रस्तुत करने के लिए सॉफ़्टवेयर में सीमा बनाना है और यह अच्छा नहीं है।

और मेरे दिमाग में एक और सवाल है, स्मृति आवंटन के लिए सी ++ "नया" ऑपरेटर मुझे त्रुटि दे रहा है, सी "malloc" ऑपरेटर के बारे में कैसे? इस मुद्दे को ठीक करने के लिए "malloc" कर सकते हैं, क्या इन दोनों के बीच कोई अंतर है?

कृपया मुझे मार्गदर्शन करें। धन्यवाद।

# 1 अद्यतन:

मैंने बहुत कोशिश की है, आदि, कोड को संशोधित मेमोरी लीक निकालने के लिए, है, लेकिन मैं 4 लाखों लोगों की तुलना में अधिक स्मृति आवंटित नहीं कर सकता। मेरा पूरा कोड "वेक्टर" में बदलना संभव नहीं है। मैं "वेक्टर" में नहीं बदल सकता, मुझे अब "नई" के साथ अपनी खुद की डेटा संरचना पर अटक जाना है। निम्नलिखित पॉइंटर्स हैं जिन्हें मैं 1 ऑब्जेक्ट प्रस्तुत करने के लिए आवंटित करना चाहता हूं।

P = new points[10000000]; // points is the class with 3 floats X, Y, Z; 
N = new Norm[10000000]; // Norm is the class with 3 floats X, Y, Z; 
V = new vNorm[10000000]; // vNorm is the class with 3 floats X, Y, Z; 
T = new Tri[10000000]; // Tri is the class with 3 integers v1, v2, v3; 
+2

क्या आप रिलीज बिल्ड चला रहे हैं? क्या आपने सीधे एक्सप्लोरर (* यानी * विजुअल स्टूडियो के बाहर) से प्रोग्राम चलाने की कोशिश की है? – paddy

+0

हां बेशक, मैं रिलीज मोड के बारे में बात कर रहा हूं, निर्माण, इंस्टाल और अन्य पीसी में भी कोशिश की। – furqan

+2

क्या आप वाकई मेमोरी लीक या एड्रेस स्पेस विखंडन का अनुभव नहीं कर रहे हैं? –

उत्तर

12

यह Windows प्रोग्रामिंग की महान मिथकों में से एक है, एक प्रक्रिया कर सकते हैं कभी नहीं रैम से बाहर रन। विंडोज एक मांग-पेजेड वर्चुअल मेमोरी ऑपरेटिंग सिस्टम है, अगर किसी प्रक्रिया को अधिक रैम की आवश्यकता होती है तो ऑपरेटिंग सिस्टम अन्य प्रक्रियाओं के स्वामित्व वाले अन्य मेमोरी पेजों को पेजिंग करके कमरे बनाता है। या प्रक्रिया स्वयं, उन पृष्ठों को स्वैप कर रही है जिनका उपयोग थोड़ी देर के लिए नहीं किया गया है।

उस मिथक को प्रोत्साहित किया जाता है जिस तरह कार्य प्रबंधक अपनी डिफ़ॉल्ट सेटिंग्स के साथ प्रक्रिया के लिए स्मृति उपयोग की रिपोर्ट करता है। यह काम सेट दिखाता है, जो रैम में मौजूद प्रक्रिया के बाइट्स की वास्तविक संख्या है। एक मान जो प्रक्रिया द्वारा आवंटित वर्चुअल मेमोरी की मात्रा से आमतौर पर बहुत छोटा होता है। ओओएम पर एक प्रक्रिया मर जाती है जब यह वर्चुअल मेमोरी आवंटित नहीं कर सकती है। टास्कमग्री, वीएम आकार मूल्य में एक और आंकड़ा। और यह आम तौर पर मर जाता है क्योंकि सभी वीएम का उपयोग नहीं किया जाता था, क्योंकि वहां कोई छेद नहीं बचा है जो काफी बड़ा है। SysInternals 'VMMap उपयोगिता यह देखने का एक अच्छा तरीका है कि प्रक्रिया अपनी पता स्थान का उपयोग कैसे करती है।

एक बड़ी वर्चुअल मेमोरी एड्रेस स्पेस प्राप्त करने के लिए एक सुंदर मौलिक ओवरहाल की आवश्यकता होती है। यद्यपि यह आज आसान है, बस प्लेटफार्म लक्ष्य के रूप में x64 को लक्षित करें। एक 64-बिट प्रक्रिया में बड़ी मात्रा में एड्रेस स्पेस उपलब्ध है, जो केवल पेजिंग फ़ाइल के अधिकतम आकार से ही सीमित है। जब तक आप/LARGEADDRESSAWARE लिंकर विकल्प का उपयोग कर 64-बिट ऑपरेटिंग सिस्टम पर वास्तव में चल रहे हैं, तब तक आप 32-बिट मोड में लम्बाई लगा सकते हैं। जो 64-बिट ऑपरेटिंग सिस्टम पर 2 जीबी से 4 जीबी तक वीएम आकार बढ़ाता है।

+0

हंस, 32 बिट एड्रेस स्पेस की सीमा, आपके सरणी के पीछे लकड़ी, सरणी के पीछे की लकड़ी की प्रकृति है, जिसे आप आसानी से प्रबंधित करने योग्य वीएम आकार को अपनी सीमा तक समाप्त कर सकते हैं (64 बिट भूमि में दिया गया है) यह एक लंबा आदेश है, लेकिन किसी 32 बिट जावा वीएम में दूरस्थ रूप से कर वाले टोमकैट सर्वर चलाने वाले किसी ने इसे अप-क्लोज और व्यक्तिगत देखा है, हमारे काम पर हमारे प्रोजेक्ट के लिए 64 बिट जावा वीएम की आवश्यकता के कारणों में से एक)। पहले दावे पर वापस देखकर, मुझे लगता है कि यह विशेष रूप से टैग किया गया है "एक प्रक्रिया ** रैम ** से कभी नहीं चल सकती है", और मैं उस पर सहमत हूं, लेकिन आप * स्मृति * से बाहर हो सकते हैं। – WhozCraig

+0

चलो वहाँ नहीं जाते हैं, शब्द "स्मृति" पूरी तरह से अस्पष्ट है। मैंने विशेष रूप से ओपी की धारणा को संबोधित किया कि वह राम से बाहर भाग गया। –

+0

मैं सहमत हूं। मैं बहुत खुश था जब काम पर 64 बिट अपनाया गया था, मैंने व्यावहारिक रूप से एक जिग (मजाक नहीं) नृत्य किया। – WhozCraig

2

प्रश्नों में से एक के लिए:

  1. malloc सी में प्रयोग किया जाता है malloc अप्रारंभीकृत स्मृति आबंटित करता है,:

    is there any diffirence between these two?

    नए और malloc के बीच विभिन्न प्रकार है। आवंटित स्मृति को free के साथ जारी किया जाना है।

  2. new संबंधित कन्स्ट्रक्टर को कॉल करके आवंटित स्मृति को प्रारंभ करता है। new के साथ आवंटित स्मृति delete (जिसे विनाशक कहते हैं) के साथ जारी किया जाना चाहिए। आवंटित स्मृति को जारी करने के लिए आपको स्मृति ब्लॉक का आकार देने की आवश्यकता नहीं है।

यह मानक (यह एक विशिष्ट संकलक लागू करता newmalloc या नहीं का उपयोग कर, इस पर निर्भर करता है) के अनुसार है कि क्या स्पष्ट नहीं new और malloc से संबंधित हैं, इसलिए इस मुद्दे को या बस new की जगह हल नहीं किया जा सकता है malloc के साथ।

आपके द्वारा दिखाए गए कोड से, त्रुटि के कारण को खोजना मुश्किल है।यह देखने के लिए कि क्या यह आपकी समस्या हल करता है, आप vector के साथ गतिशील सरणी को प्रतिस्थापित करने का प्रयास कर सकते हैं। इस बीच, आप यह जांचने के लिए valgrind का उपयोग कर सकते हैं कि आपके कोड में मेमोरी लीक है (यदि आप किसी भी तरह मेकफ़ाइल के साथ लिनक्स में अपना कोड पोर्ट कर सकते हैं क्योंकि दुर्भाग्यवश विंडोज़ पर विंडोज़ उपलब्ध नहीं है।)।

+0

विंडोज़ पर वालग्रिंड मौजूद नहीं है। मुझे यह याद आती है :-( –

+0

yup .. यह विंडोज़ समर्थित नहीं है। धन्यवाद। – furqan

+0

यह वास्तव में, जो एक सच्चा-बमर नहीं है। WinDbg आपको सबकुछ देगा (लगभग) वालग्रिंड होगा, लेकिन आपको वास्तव में चाहिए यह, और इसके लिए काम करें। – WhozCraig

2

और मेरे मन में एक और प्रश्न है, C++ दे रही है मुझे> त्रुटि, कैसे ग के बारे में "malloc" ऑपरेटर स्मृति आवंटन के लिए 'नई' ऑपरेटर? इस मुद्दे को ठीक करने के लिए "malloc" कर सकते हैं, क्या इन दोनों के बीच कोई भिन्नता है?

malloc और new के बीच मतभेद रहे हैं, उदाहरण के लिए, new अपनी स्मृति को प्रारंभ और वर्ग के निर्माता स्वचालित रूप से कॉल करेंगे। या प्रारंभ करें यदि वे आदिम प्रकार हैं (जैसे float, int, char आदि)। new द्वारा आवंटित स्मृति को delete कीवर्ड से हटा दिया जाना चाहिए जो विनाशक को बुलाता है।

सी malloc() के साथ-साथ विजुअल स्टूडियो में new ऑपरेटर आंतरिक रूप से HeapAlloc() पर कॉल करता है। HeapAlloc()VirtualAlloc() पर कॉल करें यदि आवश्यक स्मृति बहुत बड़ी है, या प्रक्रियाओं के बीच साझा की जाती है। इसलिए, यह आपके मुद्दे को जरूरी नहीं तय करेगा। वास्तव में यदि आप new का उपयोग करने के लिए सी ++ स्टिक का उपयोग कर रहे हैं।

+0

"कक्षा के निर्माता को स्वचालित रूप से कॉल करें" - अच्छी तरह से 'नया' भी प्राचीन प्रकारों के साथ उपयोग किया जा सकता है। आप यह भी शामिल कर सकते हैं कि जब आप इसका उपयोग करते हैं तो क्या होता है। – Shoe

+0

@ जुएसी हाँ .. और मेरे पास है, यह नई आवंटित स्मृति को शुरू करता है। उदाहरण के लिए आदिम प्रकारों में यह पूर्णांक और पात्रों के लिए '0' तक शुरू होता है, फ्लोट और युगल के लिए' 0.00000'। –

+0

ठीक है, लेकिन यह उनके लिए कोई कन्स्ट्रक्टर या विनाशक नहीं कहता है, क्योंकि वे कक्षाएं नहीं हैं। क्या तुमने देखा कि मेरा क्या मतलब है? – Shoe

संबंधित मुद्दे

 संबंधित मुद्दे