2013-06-04 28 views
8
Şu anda bellek 2.5GB değerinde hakkında çok büyük veri kümeleri ile çalışıyorum

..std :: vektör takas bellek parçalanmasına neden oluyor?

Şu anda 1) Meta veri 2) boost::ptr_list<MemoryBlock>

içeren sınıf Verilerinin bir vektör kullanarak bu depolamak.Bu

MemoryBlock sınıfı 1) Meta veri 2) std::vector<XYZ>

doldurma i 50.000 grupları benim std::vector<xyz> ayıracağı içerir. Vektörümün uzaysal boyutları büyürse, yeni bir bellek bloğu oluşturur ve vektörü uygun boyuta küçültmek için std::vector<XYZ>(Points).swap(Points)'u kullanırım.

Şimdi sorun ... Dizimi yeniden boyutlandırmak için swap numarasını kullandığımda, tüm verilerimi temizledikten ve yeni bir veri kümesine yükledikten sonra std :: bad_alloc özel durumlarına girmeye başladım.

Yükleyebileceğim veri miktarı önemli ölçüde küçülüyor ... Verilerimi her açtığımda ve yeni bir veri kümesine yüklediğimde bunu yapmaya devam edeceğim ... Örneğin, İlk veri kümem yüklenecek 100,000,000 değerleri

o 70.000.000 değerleri

dahaki sefere 50.000.000 değerleri

dahaki sefere yükleyecektir

dahaki sefere ilk düşüncem bir bellek sızıntısı olduğunu

20.000.000 değerleri vs ... ama orada tanımlayabildiğim bir şey değil. Takas hariç koddaki her şey, herhangi bir problemle çok uzun bir süre boyunca yaygın olarak kullanıldı.

Takas/mekansal boyut kontrolünü kullanmazsam, her şey devam eder ve düzgün çalışır.

herhangi bir fikir?!? İşte Düzenleme

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; 
} 

bu kullanarak kod bölümüdür ..

    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; 
         } 

        } 
+3

Her bellek ayırma, bellek parçalanmasına neden olma potansiyeline sahiptir. – PlasmaHH

+1

Bence C++ 11 vektörü :: shrink_to_fit ve yapıcılar (büyümeye devam ederken kopyalama yerine) problemlerinizi hafifletebilir. C++ 11 seçeneği var mı? – mirk

+0

C++ 11 bir seçenek değildir. Her tahsisin biraz parçalanmaya neden olabileceğini anlıyorum, ama gördüğüm derece değil. – user1000247

cevap

6

Bu teknik arada çağrılara Check_MemBlock_Size() biraz daha dinamik ayırmayı yaparsanız parçalanması garanti gibi görünüyor . Bunun nedeni, daha küçük parçanızı ayırdıktan sonra 50K'lık tahmininizi serbest bırakmanız, böylece bellekte 50K'lık bir nesne deliği oluşturmanızdır, bu da artık daha fazla bellekle kısmen doldurulabilmektedir, bu da MemoryBlock numaralı telefonunun bir sonraki yeniden kullanımınızı kullanamaz.

Bu 50K nesnesini ayırmak için geçici bir vektör yerine global bir vektör oluşturabilirsiniz. Ardından, yeni bir 50K nesne vektörünü yeniden boyutlandırmak yerine, yeni bir MemoryBlock'u yeniden oluşturduğunuzda, yalnızca global olanı değiştirin. Onu küçültmek istediğinde, tekrar küresel olanla değiştir. 50K ayrılmış hafızayı bu şekilde yeniden kullanmak, bu tahsisatın katkıda bulunabileceği parçalanmayı ortadan kaldıracaktır. Kaçak olmadığından eminseniz, programınızda başka parçalanma kaynakları olabilir. Tipik olarak parçalanma, her biri değişken yaşam süreleri olan dinamik olarak ayrılmış büyük ve küçük nesnelerin bir karışımından kaynaklanır.Bunu çözmek için birçok yol var, ancak bunun üstesinden gelmenin bir yolu hafıza havuzları. Bu anlamda bir havuz, aynı boyutta ve aynı ömürde olan, özel bir ayırma birimi içinde gruplandırılmış bir nesneler topluluğudur. Bu tür bir belleğin ayrılması, havuzuna geri döndürülür. Bellek, sisteme hiçbir zaman delete ile geri gönderilmezse, havuz, daha önce aynı nesne türü için ayrılmış olan belleği yeniden kullanmak için gelecekteki ayırmalara izin vererek parçalara ayırma ile mücadele eder. Havuzlar en yüksek çalışma zamanı kullanım oranına ulaşır ve parçalanma bundan daha kötü değildir.

+0

Teşekkürler! Bu işe yarayabilir gibi geliyor. Ben bir deneyin – user1000247

+0

Bu işe yaramadı :( – user1000247

+0

@ user1000247: Ne demek istiyorsun? – jxh

İlgili konular