Büyük bir monolitik uygulama özel bir yapı oluşturmaya çalışıyorum. Çözmeyi denediğim sorun, büyük bellek ayırmalarını çoğaltmak (30-80 gigabayt, işletim sistemi tarafından karar vererek) çoğaltmaktır. Sorunun bir negatif 32 bitlik tamsayı değerine yeniden boyutlandırılan bir std :: vektörü olduğunu düşünüyorum. Bu davranışı sergileyen tek platform Solaris'tir (belki de bu tür bitişik bellek parçalarını başarılı bir şekilde tahsis etmeyi başaran tek platformdur). Genel olarak std :: vektörünü sınıfımla değiştirebilir, tüm çağrıları gerçek vektöre aktarabilir, şüpheli ayırmaları izleyebilir miyim (size > 0x7FFFFFFFu)
? Seçmeli olarak size_t
ve resize()
yöntemlerini kullanan kurucuyu değiştirebilir misiniz? Belki de küresel operatörü yeni kandırıyor mu?Devasa bellek ayırmalarını izlemek için global operatörü yeniliyor mu?
cevap
Neden böyle bir şey yapmıyorsunuz? hemen sorunu bulur if
bir kesme noktası ayarlama
void *operator new(size_t size)
{
// if (size > MAX_SIZE) ...
return malloc(size);
}
void *operator new [](size_t size)
{
// if (size > MAX_SIZE) ...
return malloc(size);
}
.
Evet, başarmak istediğim buydu. Elbette, 'yeni operatör' platformun standart kütüphanesinde zaten tanımlanmıştır, bu yüzden sadece ikinci bir uygulama sağlayamam. –
Evet yapabilirsin. Denedin mi? Bağlantı hataları alıyor musunuz? – detunized
Eğer böyle yapabilsem harika olur. Deneyeceğim. –
Yaptığınız anda vektörünüzde özel bir ayırıcı sağlayabilirsiniz.
std::allocator
'a yetki verebilirsiniz ve istenen bellek boyutunu ilk olarak güvenlik duvarı ile güvenlik altına alabilirsiniz.
Bakın, sorun şu ki, kodun hangi bölümünün yanlış olduğunu bilmiyorum. Tüm kod tabanı (üçüncü taraf kütüphaneleri dahil), bir vektörün kullanıldığı her yerde özel ayırıcılar ile değiştirmek mümkün değildir. –
Evet, o zaman bu daha zor. Q, zaten hangi vektörün olduğunu bildiğiniz gibi okuyun. Platformunuz, calltack oluşturarak yığın bloklarını ilişkilendirmek için herhangi bir araç sunuyor mu? –
Şüpheli bir durum tespit ettiğimde çağrı yığınını kaydedebilirim. Soru, bir vektörü kullanarak her bir sınıfı değiştirmeden, küresel olarak nasıl algılayacağıdır. –
Sorunlu platformda std::vector
sınıfının uygulanmasına göz atın. Her bir uygulama, bellek yönetimini farklı şekilde işler (örneğin, vektörün şu andaki tahsisat boyutu dışında bir nesne eklediğinizde, şu anda ayrılmış alanın iki katı). Nesneleriniz yeterince büyükse ve/veya vektöre çok sayıda giriş eklendiyse, bilgisayardaki mevcut (bitişik) belleğin ötesine geçmeye çalışmak mümkün olabilir. Bu durumda, bu vektör için özel bir ayırıcıya bakmak isteyeceksiniz.
Bir vektörde çok fazla büyük öğe saklıyorsanız, başka bir koleksiyona (örneğin, std::list
) bakmak veya gerçek nesneler yerine işaretçileri depolamayı deneyebilirsiniz.
Çözmeyi denediğim sorun, daha az bellek kullanmak için kodun nasıl değiştirileceği değil.Vector.resize ((size_t) (- 1)) 'işlevini etkin bir şekilde yürüten kod parçasını bulmaya çalışıyorum. Bu parça belirlendikten sonra, düzeltmek için önemsiz bir görev olmalıdır. –
Koşullu kesme noktası yeteneğine sahip bir hata ayıklayıcıya erişiminiz varsa, bu hile yapar. Aksi halde, koleksiyonunuzu ikiye bölmeyi deneyin ve aynı sorunla karşılaşıp karşılaşmadığınızı test edin. Sorunu görene kadar koleksiyonunuzu kalan öğelerin yarısına kadar artırın. Bağırsak reaksiyonum, stok tahsisatçısının, mevcut kapasitesini iki katına çıkararak koleksiyonunuzun kapasitesini artırarak ve tahsis etmek için bitişik belleğin tükenmesiyle birlikte bir yere yerleştirilebilecektir. –
kod, QA ortamında müşterinin sitesinde çalıştırılacaktır. Bu çalışmanın sonuçlarına erişebilirim (log dosyaları), ancak bir hata ayıklayıcısında çalıştırmasını talep edemem. –
Atanmayı izlemek için kendi allocator
türünü std::vector
türüne sağlayabilirsiniz. Ama bunun sebebi şüpheliyim. İlk olarak, (30-80GB) boyutlarına bakarak, bunun 64 bitlik bir kod olduğu sonucuna varıyorum. 32-bit negatif tamsayı değeri, 64-bit olan vektör büyüklüğüne nasıl değer kazandırabilirdi, değeri korumak için önce 64-bit'e yükseltilmiş olurdu? İkincisi, eğer bu problem sadece Solaris'te gerçekleşirse, o zaman farklı bir problemi gösterebilir. Hatırladığım kadarıyla, Solaris, tahsis üzerine belleği işleyen tek işletim sistemidir, diğer işletim sistemleri, yalnızca bu bellek sayfaları gerçekte kullanılıncaya kadar tahsis edilen adres alanını işaretler. Bu yüzden kullanılmayan tahsisleri arardım.
Negatif 32 bitlik değer, vektör boyutuna nasıl dönüştürebilir? Bunun gibi bir şey: 'uint32_t count = (uint32_t) GetNumberOfThings(); std :: vektör şeyler (Thing(), count); 'GetNumberOfThings 'hatada -1 döndürdüğünde. Ve evet, mevcut kod tabanı çok fazla 32 bit büyüklükte değişken kullanır ve hatta 32 bit boyutunda özel bir vektör uygulaması vardır. Sorun, sorunlu kod parçalarını takip ediyor ... –
- 1. jemalloc paylaşılan kitaplığı bellek ayırmalarını hızlandırmak için önceden yüklenemedi
- 2. Yükseltme :: havuzunu kullanarak bir std :: vektöründe bellek ayırmalarını yönetme
- 3. 'OR' operatörü öngörüyor mu?
- 4. C# ve Visual Studio 2015'te bellek ayırmalarını görüntüleme?
- 5. Internet Explorer'da jscript bellek kullanımını izlemek için ne kullanırsınız?
- 6. Devasa bellek alan liste nesneleriyle interaktif olarak çalışın
- 7. "???" operatörü kısa dolaşımını kullanıyor mu?
- 8. C#: Çok tuşlu kısayolları global olarak izlemek için kullanabileceğiniz en iyi kanca hangisidir?
- 9. iPhone bellek sızdırılıyor mu?
- 10. Değişiklik için bir özelliği izlemek
- 11. ThreadPoolExecutor cihazım bellek sızdırıyor mu?
- 12. Mremap bellek büyümeye "başlatıyor" mu?
- 13. Burada C++ operatörü aşırı yükleniyor mu?
- 14. Bir JFrame içinde JPanels'i yeniliyor
- 15. XAML verileri global değişkene bağlanıyor mu?
- 16. Metin ve veri bölümleri için devasa sayfalar kullanımı
- 17. Yok yöntem çağrıları ben Instruments kullanarak cihazda bellek ayırmalarını Uygulamamı profile çalışıyorum iz
- 18. C++ programı değişiklikleri izlemek için dizin
- 19. Kullanıcı etkinliğini izlemek için çerçeve var mı?
- 20. nasıl linux bir dosyayı izlemek için osx
- 21. Sistem izlerini izlemek için çekirdek modülü?
- 22. Yürüyüşümü izlemek için bir Android projesinde çalışıyorum.
- 23. Google AccessToken Firebase'de Nasıl Yeniliyor? #AskFirebase
- 24. Windows mobil cihazlarda datagrid nasıl yeniliyor?
- 25. Kullanıcı AngularJs'de denetleyiciyi güncelleştirdiğinde $ durumu nasıl yeniliyor?
- 26. Kayıt Defteri Ayarlarını VBScript ile Nasıl Yeniliyor?
- 27. Vektörle ilgili bir sorun mu var? Bellek?
- 28. operatörü sil - nasıl uygulanır?
- 29. Scala için `` `güç operatörü oluşturma?
- 30. Docker bellek kullanımını doğru olarak bildirmiyor mu?
32 bit değeri IMO'nun 30-80 GigaByte ile sonuçlanamaz, yani 64 bit –
anlamına gelir Bir 0xFFFFFFFF 8 baytlık yapılar dizisi ~ 34 gigabayt alır. –
Düzeltilmeye hazırlanıyorum –