2015-01-22 14 views
18

Czy aplikacja .NET 3.5 może poinformować środowisko wykonawcze .NET: "hej, zamierzam użyć później pamięci n MB, więc proszę albo zatwierdzić teraz teraz lub nie teraz teraz? "Pamięć wstępnie przydzielona (gwarancja) w aplikacji .NET

Kontekst dla tego: Mam aplikację konsoli C#, która uruchamia kwerendę bazy danych, która zwraca wiele danych, a następnie przetwarza je. Zapytanie może trwać bardzo długo (godziny), a zużycie pamięci stale wzrasta wraz z odczytywaniem wyników. Po zakończeniu zapytania następuje natychmiastowy wzrost pamięci w związku z przetwarzaniem, które muszę wykonać. Jeśli komputer nie ma wystarczającej ilości pamięci RAM, aplikacja nie działa w tym momencie - po marnowaniu godzin na zapytanie! Jest to bardzo frustrujące dla użytkownika. Jeśli nie ma wystarczającej ilości pamięci RAM, chciałbym, aby aplikacja szybko zawodziła.

Oczywiście, mógłbym spróbować jakiś hack jak przydzielając dużą tablicę, której tak naprawdę nie potrzebuję, a następnie ustawiając ją na wartość null tuż przed tym, jak naprawdę potrzebuję pamięci, ale to nie jest idealne, ponieważ może to faktycznie spowodować procesowi zabrakło pamięci, gdy w przeciwnym razie byłby wystarczający. Idealnie nie chciałbym używać więcej pamięci niż potrzeba, ale po prostu wcześnie przestań działać, chyba że pewna kwota może być zagwarantowana przez cały czas pracy mojej aplikacji. czy to możliwe?

+0

Czy jesteś pewien, że przetwarzanie jest związany z CPU na dane w pamięci? Jeśli chodzi o godziny, wydaje się, że wiele IO również musi się dziać? – Enigmativity

+0

Ile wynosi ilość danych pobranych z zapytania w mb (około)? – ceztko

+2

To jest interesujący problem, na pewno. Być może będzie możliwe buforowanie wyników kwerend do pamięci dodatkowej (dysku) lub lokalnej bazy danych przed przetworzeniem. Następnie, jeśli coś pójdzie nie tak, możesz szybko odzyskać dane z lokalnego komputera. Tylko myśl. – STLDeveloper

Odpowiedz

20

można spróbować użyć klasy MemoryFailPoint:

try 
{ 
    using (new System.Runtime.MemoryFailPoint(20)) // 20 megabytes 
    { 
     ... 
    } 
} 
catch (InsufficientMemoryException) 
{ 
    ... 
} 
+1

Miłe znalezisko. W tym miejscu chciałbym również doradzić pytającemu, aby utrzymał wyniki z zapytania i udostępnił dowolne połączenie/interfejs do bazy danych. Po tym, jak wyniki mogą być ponownie załadowane z pamięci, aby zapewnić, że tylko pobrane dane są w pamięci i nie ma innych wewnętrznych pamięci podręcznych. Należy również sprawdzić kod przetwarzania, aby upewnić się, że nie ma wycieków. – ceztko

+0

To wygląda na przydatne - dzięki! MSDN mówi: "MemoryFailPoint nie daje żadnych gwarancji dotyczących długoterminowej dostępności pamięci podczas okresu użytkowania bramki", więc nie jest to niezawodne, ale wciąż obiecujące. – EM0

+0

Po wypróbowaniu tego przez jakiś czas, niefortunnie uznałem, że jest zbyt niewiarygodne, aby mieć jakiekolwiek praktyczne zastosowanie (dla mnie). Często konstruktor MemoryFailPoint generował wyjątek, ale mimo to przetwarzanie zakończyłoby się pomyślnie. Innym razem, MemoryFailPoint nie wyrzucił, ale przetwarzanie później i tak zabrakło pamięci. – EM0

Powiązane problemy