Wzorzec puli
obiektów polega na użyciu zbioru zainicjowanych obiektów, które są trzymane w
gotowości do użycia, a nie alokowane lub deklarowane na żądanie. Klient puli
obiektów żąda obiektu z tej puli i wykonuje na nim pewne operacje. Po
skończeniu, zamiast niszczyć obiekt, zwraca go do puli. Wzorzec ten znajduje
swoje zastosowanie w przypadkach dotyczących bardzo dużej liczby obiektów –
problemach z pamięcią i wydajnością.
Struktura
Uczestnicy
- Zarządca - dysponuje pulą, definiuje punkt dostępu do obiektów, zarządza cyklem życia obiektów.
- Obiekt - jest zarządzany przez zarządcę, definiuje swój cykl życia, może być powtórnie wykorzystany.
- Klient - żąda dostępu do obiektów z puli za pośrednictwem zarządcy.
Obiekt
odpowiedzialny za tworzenie obiektów nie tworzy ich za każdym razem, gdy zażąda
tego klient. Przechowuje on grupę aktywnych obiektów w puli. Obiekty te są
przydzielane klientów w miarę ich potrzeb. Po wykorzystaniu, zwracane są do
puli w zresetowanym stanie (w jakimś rozsądnym stanie na potrzeby ponownego
użycia). W ten sposób rozwiązany jest problem racjonalnego wykorzystania
zasobów, ponieważ obiekty mogą być wykorzystane wielokrotnie. Wydajność takiego
rozwiązania jest uzależniona od liczby aktywnych obiektów i charakterystyki czasowej
nadchodzących żądań. Obiekt z puli jest dostarczany w przewidywalnym czasie,
podczas gdy rozrzut w czasie tworzenia nowego obiektu, szczególnie przez sieć,
może być duży.
Konsekwencje stosowania
Zalety:
- ograniczenie zużycia pamięci - racjonalne zarządzanie nią;
- ograniczona liczba jednocześnie wykorzystywanych obiektów;
- lepsza hermetyzacja - klient nie zajmuje się tworzeniem i obsługą obiektów.
- pula obiektów służy jednak do zarządzania grupą obiektów nierozróżnialnych;
Część źródeł nie
poleca stosowania puli obiektów, szczególnie dla obiektów, które tylko zajmują
pamięć i nie odnoszą się do zewnętrznych zasobów. Poza tym, stosowany w
nowoczesnych językach programowania carbage
collector stosunkowo szybko radzi sobie z alokowaniem obiektów. Dodatkowo,
większość odśmiecaczy skanuje referencje do "żywych" obiektów, a nie
pamięć zajmowaną przez te obiekty. To znaczy, że małym kosztem można się pozbyć
każdej ilości "martwych" obiektów bez referencji. Dla
porównania, utrzymywanie dużej ilości "żywych", lecz nieużywanych
obiektów zwiększa czas odśmiecania. W większości przypadków, programy używające
odśmiecania zamiast bezpośredniego zarządzania pamięcią działają szybciej.
Zastosowanie
Pula obiektów stosowana jest w celu spowodowania znacznego wzrostu wydajności w przypadkach gdy:
- koszt powoływania nowych obiektów jest wysoki;
- częstotliwość tworzenia nowych obiektów jest wysoka;
- liczba obiektów będących w użyciu jest mała.
Przykład
Największe korzyści ze stosowania tego wzorca są odczuwalne w przypadkach obsługi tworzenia obiektów w obszarach takich jak:
- połączenia bazodanowe;
- połączenia gniazdowe;
- wątki;
- duże obiekty graficzne.
// Manager obiektów z puli
public class PoolManager {
// Reprezentuje element puli
wraz z flagą blokowania
private static class
PoolItem {
boolean inUse = false;
Object item;
PoolItem(Object item) {
this.item = item;
}
}
// Tablica obiektów puli
private ArrayList items =
new ArrayList();
// Dodawanie obiektów do puli
public void add(Object item) {
items.add(new
PoolItem(item));
}
// Wyjątek reprezentujący brak
wolnych obiektów w puli
static class
EmptyPoolException extends Exception {}
// Pobieranie wolnego obiektu
z puli
public Object get() throws
EmptyPoolException {
// Zwracamy pierwszy wolny obiekt
item'u (items[i].inUse = false)
// i blokujemy go lub wywołujemy
EmptyPoolException
}
// Zwalnianie obiektu z puli
public void release(Object o) {
// Wyszukujemy item z puli
posiadający obiekt o i zwalniamy flagę zajętości
// (item[i].inUse = false) lub
wyjątek jeśli nie znaleziono
}
Źródło: http://jdn.pl/node/1241
Źródła
Brak komentarzy:
Prześlij komentarz