Moja aplikacja wymaga dużej ilości pamięci i dużej struktury danych, aby wykonać swoją pracę. Często aplikacja wymaga więcej niż 1 GB pamięci, aw niektórych przypadkach moi klienci naprawdę muszą korzystać z 64-bitowej wersji aplikacji, ponieważ mają kilka gigabajtów pamięci.Zmuszanie systemu Windows do ładowania bibliotek DLL w miejscach, w których pamięć jest minimalnie pofragmentowana.
W przeszłości mogłem z łatwością wytłumaczyć użytkownikowi, że jeśli pamięć osiągnęła 1,6 do 1,7 GB pamięci, było to "za mało pamięci" lub naprawdę blisko sytuacji "braku pamięci" i było to konieczne zmniejszyć ich pamięć lub przejść do wersji 64-bitowej.
W zeszłym roku zauważyłem, że często aplikacja zużywa tylko około 1 GB, zanim zabraknie jej pamięci. Po pewnych badaniach wydawało się, że przyczyną tego problemu jest fragmentacja pamięci. Użyłem VMMAP (narzędzia SysInternals) do obejrzenia użycia pamięci w mojej aplikacji i zobaczyłem coś takiego:
Pomarańczowe obszary to pamięć przydzielona przez moją aplikację. Purpurowe obszary to kod wykonywalny.
Jak widać w dolnej połowie obrazu, purpurowe obszary (które są bibliotekami DLL) są ładowane pod wieloma różnymi adresami, co powoduje, że moja pamięć jest pofragmentowana. Nie stanowi to problemu, jeśli mój klient nie ma dużej ilości danych, ale jeśli mój klient ma zestawy danych, które zajmują więcej niż 1 GB, a część aplikacji potrzebuje dużego bloku pamięci (np. 50 MB), może to spowodować awarię alokacji pamięci, powodując awarię mojej aplikacji.
Większość moich struktur danych bazuje na STL i często nie wymaga dużych porcji ciągłej pamięci, ale w niektórych przypadkach (na przykład bardzo duże ciągi), naprawdę potrzebna jest przyległa blokada pamięci. Niestety nie zawsze jest możliwa zmiana kodu tak, aby nie potrzebował tak ciągłego bloku pamięci.
Pytania są:
- W jaki sposób można wpływać na lokalizację, w której DLL są ładowane do pamięci, bez jawnie przy użyciu rebase na cały DLL na komputerze klienta, albo bez ładowania cały DLL wyraźnie.
- Czy istnieje sposób określania adresów ładowania plików DLL we własnym pliku manifestu aplikacji?
- Czy istnieje sposób, aby powiedzieć systemowi Windows (za pośrednictwem pliku manifestu?), Aby nie rozrzucać bibliotek DLL (myślę, że to rozproszenie nazywa się ASLR).
Oczywiście najlepsze rozwiązanie to takie, na które mogę wpływać z pliku manifestu mojej aplikacji, ponieważ polegam na automatycznym/dynamicznym ładowaniu bibliotek DLL przez system Windows.
Moja aplikacja to aplikacja mieszana (zarządzana i niezarządzana), chociaż główna część aplikacji jest niezarządzana.
Wszelkie sugestie?
Czy to jest coś, co może ci pomóc? http://msdn.microsoft.com/en-us/library/f7f5138s.aspx – detunized
mmm, czy naprawdę potrzebujesz tyle pamięci w tym samym czasie? Monitor procesu przechowuje logi w pamięci wirtualnej i w razie potrzeby przenosi dane tylko do przestrzeni adresowej pamięci procesu, sprawdź http://blogs.msdn.com/b/oldnewthing/archive/2004/08/10/211890.aspx, aby uzyskać kod przykład –
Nie jestem pewien, czy wszyscy pozostawiający odpowiedź rozumieją konsekwencje ASLR: http://en.wikipedia.org/wiki/ASLR –