[SwingWorker] Czy można uruchamiać wątki spod SwingWorkera

0

Witam
Mam aplikację ze środowiskiem graficznym i długotrwałym procesem "odpalanym" spod tego środowiska przy pomocy SwingWorkera. Do mojej aplikacji chciałbym dopisać wątek, który sprawdzałby ilość pamięci operacyjnej zużywanej przez program.

Pytanie brzmi: jak to zrobić? Czy bezpiecznie byłoby utworzyć nowy wątek w metodzie doInBackground SwingWorkera? Czy wybrać jakieś inne rozwiązanie, a jeśli tak to jakie?

0

Dodatkowy wątek nie powinien być problemem. Osobiście jednak odpaliłbym go poza SW ponieważ jego zadanie nie jest wprost powiązane z SW. Taki clean code.

0

Jeżeli istotne by było w jakim momencie sprawdzany jest stan pamięci w odniesieniu do jakichś operacji w procedurze doInBackground(), to miałoby to sens. W innym wypadku nie.
Innym rozwiązaniem jest użycie Timera do odczytu co jakiś czas stanu wolnej pamięci (np. co 5 s) i buforowanie jej jako daną aplikacji.

Powinieneś jeszcze wiedzieć, że proste sprawdzanie Runtime.getFreeMemory() jest bezwartościowe z punktu widzenia specyfiki obsługi pamięci przez Javę. Prawdziwa ilość wolnej pamięci możliwej do przydzielenia dla aplikacji Java, to:

Runtime r = Runtime.getRuntime();
long realFreeMemory = r.maxMemory() - r.totalMemory() + r.freeMemory();

Jeżeli wartość ta spadnie poniżej 10% maxMemory(), to można zwiększyć maksymalny rozmiar pamięci dla JVM, a jeżeli nie będzie to możliwe, to zacząć zajmować się optymalizacją wykorzystania pamięci.

Chodzi o to, że cała dostępna dla JVM pamięć możliwa potencjalnie do przydzielenia z systemu operacyjnego, to maxMemory(), cała już przydzielona pamięć, to totalMemory(), z której (najczęściej) niewielki wycinek, to freeMemory() dostępny do użycia natychmiast. Natomiast w miarę potrzeby JVM może przydzielić sobie (i swoim aplikacjom) całą wielkość ( maxMemory() - totalMemory() ), do czego potrzebne jest jej wywołanie systemowe (na przykład malloc() lub coś jeszcze niższego). Wartość maxMemory() jak na razie nie ma prawa zmienić się podczas działania aplikacji bo wymagałoby to restartu JVM, można więc ją trzymać jako finalną stałą statyczną odczytaną na początku działania aplikacji. Pozostałe dwie są już dynamiczne.
Java zakłada przydzielanie jej wyłącznie spójnego z punktu widzenia adresowania kawałka pamięci, dlatego jak na razie największą wartością totalMemory () jest w systemie 32-bitowym 1,5 GB RAM (a wersji 64-bitowej chyba wciąż nie ma). To może się zmienić w przyszłości.
Warto też wiedzieć, że odśmiecacz operuje wyłącznie w obrębie totalMemory, a przydzielona pamięć podzielona jest na aplikacje i ich dane, obiekty czekające na usunięcie oraz pamięć wolną czyli freeMemory().
Wyjątek OutOfMemoryException jest generowany jeżeli totalMemory() == maxMemory(), a ostatnie odśmiecanie nie zwolniło więcej niż 10% wcześniejszej wartości freeMemory() i zajęło więcej niż 90% czasu pracy procesora.

0

dzięki wielkie za obie odpowiedzi :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1