मैं वर्तमान में स्मृति की 2.5GB के लायक के बारे में बहुत बड़े डेटा सेट के साथ काम कर रहा हूँ ..std :: वेक्टर स्वैप मेमोरी विखंडन का कारण बनता है?
मैं वर्तमान में कक्षा डाटा का एक वेक्टर कि 1) मेटा डेटा 2) boost::ptr_list<MemoryBlock>
शामिल का उपयोग करके इस भंडारण कर रहा हूँ MemoryBlock वर्ग 1) मेटा डाटा 2) std::vector<XYZ>
जब पॉप्युलेट, मैं 50,000 के समूह में मेरी std::vector<xyz>
आरक्षित हैं। यदि मेरे वेक्टर के स्थानिक आयाम बड़े हो जाते हैं, तो मैं एक नया मेमोरीब्लॉक बनाउंगा और वेक्टर को उचित आकार में कम करने के लिए std::vector<XYZ>(Points).swap(Points)
का उपयोग करूंगा।
अब समस्या ... ऐसा लगता है जब मैं स्वैप चाल का उपयोग अपने सरणी आकार बदलने के लिए, मैं सेट एक नया डेटा में अपने डेटा और लोड हो रहा है के सभी साफ करने के बाद std :: bad_alloc अपवादों में चलाने के लिए शुरू कि।
डेटा की मात्रा है कि मैं में लोड कर सकते हैं तेजी से सिकुड़ता है ... यह तो हर बार जब मैं सेट ... एक नया डेटा में अपने डेटा और लोड स्पष्ट करने के लिए उदाहरण के लिए, मेरे प्रारंभिक डेटा सेट में लोड होगा जारी रहेगा 100000000 मूल्यों
अगली बार 70,000,000 मूल्यों
अगली बार 50,000,000 मूल्यों
अगली बार लोड होगा 20,000,000 मूल्यों आदि ...
मेरी पहली सोचा एक स्मृति रिसाव है, लेकिन वहां कुछ भी नहीं है जिसे मैं पहचानने में सक्षम हूं। स्वैप को छोड़कर कोड में हर चीज का उपयोग किसी भी समस्या के साथ बहुत लंबे समय तक बड़े पैमाने पर किया जाता है।
यदि मैं स्वैप/स्थानिक आयाम जांच का उपयोग नहीं करता, तो सब कुछ जारी रहता है और ठीक से काम करता है।
कोई विचार?!
संपादित
bool Check_MemBlock_Size(MemoryBlock &CurrMemblock, XYZ CheckPoint){
// Set a minimum of 5000 points in each memory block regardless of physical size..
if(CurrMemblock.PointsArr.size() > 5000){
XYZ TestMin, TestMax;
TestMin = CurrMemblock.Min;
TestMax = CurrMemblock.Max;
// Check what the bounding box would be if we included the check point..
if(TestMax.x < CheckPoint.x)
TestMax.x = CheckPoint.x;
if(TestMax.y < CheckPoint.y)
TestMax.y = CheckPoint.y;
if(TestMax.z < CheckPoint.z)
TestMax.z = CheckPoint.z;
if(TestMin.x > CheckPoint.x)
TestMin.x = CheckPoint.x;
if(TestMin.y > CheckPoint.y)
TestMin.y = CheckPoint.y;
if(TestMin.z > CheckPoint.z)
TestMin.z = CheckPoint.z;
// If the new bounding box is too big, lets break it off.
if(fabs(TestMax.x - TestMin.x) > 100 || fabs(TestMax.y - TestMin.y) > 100 || fabs(TestMax.z - TestMin.z) > 50){
std::vector<XYZ>(CurrMemblock.PointsArr).swap(CurrMemblock.PointsArr);
return false;
}
}
return true;
}
यहाँ इस का उपयोग कर कोड के खंड है ..
if(Check_MemBlock_Size(*MemBlock, NewPoint) == false){
Data->MemoryBlocks.push_back(MemBlock);
try {
MemBlock = new MemoryBlock();
} catch (std::bad_alloc) {
printf("Not enough memory\n");
delete Buffer;
break;
}
BlockSize = 0;
try{
MemBlock->PointsArr.reserve(MaxBlockSize);
} catch(std::bad_alloc){
delete MemBlock;
delete Buffer;
printf("Not enough memory\n");
break;
}
}
// Push the point to our current memory block
BlockSize++;
MemBlock->PointsArr.push_back(NewPoint);
.... // More stuff going on here.. irrelevant
// push a new memory block if we hit the block point limit.
if(BlockSize >= MaxBlockSize){
Data->MemoryBlocks.push_back(MemBlock);
try {
MemBlock = new MemoryBlock();
} catch (std::bad_alloc) {
printf("Not enough memory\n");
delete Buffer;
break;
}
BlockSize = 0;
try{
MemBlock->PointsArr.reserve(MaxBlockSize);
} catch(std::bad_alloc){
printf("Not enough memory\n");
delete MemBlock;
delete Buffer;
break;
}
}
प्रत्येक स्मृति आवंटन में स्मृति विखंडन का कारण बनने की क्षमता है। – PlasmaHH
मुझे लगता है कि सी ++ 11 वेक्टर :: shrink_to_fit और रचनाकारों को स्थानांतरित करें (बढ़ते समय प्रतिलिपि बनाने के बजाय) आपकी समस्याओं को कम कर सकते हैं। विकल्प पर सी ++ 11 है? – mirk
सी ++ 11 एक विकल्प नहीं है। मैं समझता हूं कि प्रत्येक आवंटन कुछ विखंडन का कारण बन सकता है, लेकिन जिस डिग्री को मैं देख रहा हूं वह नहीं। – user1000247