W Javie istnieje możliwość zwiększania wydajności działania aplikacji poprzez zmianę sposobu użycia pamięci. Istnieje możliwość użycia Huge Memory Pages. Pozwalają one na użycie przez aplikację stron pamięci o większym rozmiarze niż standardowe 4kB (np. w przypadku Linuksa o rozmiarze 2048kB).

Użycie takich stron pozwala na zmniejszenie ilości mapowań dokonywanych przez TLB (Translation lookaside buffer). Niestety, przynajmniej w przypadku Linuksa przed użyciem takiej pamięci należy odpowiednio skonfigurować system operacyjny, czyli zarezerwować odpowiedni obszar pamięci, który zostanie użyty przez aplikacje. Trzeba pamiętać, że będzie on miał nastepujące właściwości:

  • obszar pamięci o dużych rozmiar stron będzie dostępny tylko dla aplikacji, które potrafią i chcą z niego korzystać (czyli jeżeli przeznaczymy za dużo pamięci na ten obszar, może zabraknąć RAMu dla innych aplikacji działających w ramach systemu operacyjnego)
  • pamięć ta nigdy nie zostanie zapisanie w pamięci tymczasowej (swap)
  • aplikacja musi mieścić się w całości w ramach tego obszaru, więc warto pamiętać że pamięć zajmowana przez JVM to jest suma dwóch wartości, definiowanych przez parametry -Xmx oraz -XX:MaxPermSize

Konfiguracja systemu operacyjnego Linuks


Konfigurację Huge Pages może zostać wykonana na działającym systemie, ale w przypadku za dużej fragmentacji pamięci może się nie powieść. W zawiązku z tym po zapisaniu zmian w pliku /etc/sysctl.conf przydatny może byc restart serwera.

Pierwszym krokiem będzie zdefiniowanie maksymalnego obszaru pamięci, jak ma zostać przeznaczony dla JVM. Najłatwiej zrobić to, umieszczając w pliku /etc/sysctl.conf następujący zapis:

73
kernel.shmmax = 1073741824

Wartość dla parametru należy podać w bajtach, ja zdefiniowałem ją na 1GB (1024 * 1024 * 1024). Parametr ten definiuje maksymalny obszar pamięci jaki za zostać przeznaczony dla aplikacji, ale wymagana jest jeszcze zdefiniowanie faktycznej ilości stron pamięci, jaka zostanie użyta. Robi się to przy użyciu parametru:

74
vm.nr_hugepages = 512

Rozmiar pojedynczej strony pamięci można sprawdzić przy użyciu plecenia:

grep Hugepagesize /proc/meminfo

Kolejnym krokiem będzie utworzenie specjalnej grupy w systemie operacyjnych, której członkowie będą mieli możliwość korzystania z tej specjalnej pamięci:

groupadd hugepgs

Teraz trzeba jeszcze poznań numer GID tej grupy:

grep hugepgs /etc/group

W moim przypadku będzie to numer 1005.

Teraz jeszcze należy poinformować system, że członkowie tej grupy będą mieli możliwość zapisywania do pamięci:

75
vm.hugetlb_shm_group = 1005

Dodajmy użytkownika jboss do zdefiniowanej grupy:

usermod -aG hugepgs jboss

Ostatnim krokiem będzie możliwości blokowania stron przez danego użytkownika. Robi się to w pliku /etc/security/limits.conf poprzez umieszczenie takiego wpisu:

61
62
jboss soft memlock unlimited
jboss hard memlock unlimited

Tym sposobem system operacyjny jest już skonfigurowany poprawnie, więc pozostaje uruchomić maszynę wirtualną tak, aby wykorzystała dostępną pamięć z dużymi rozmiarami strony. Robi się to przekazując parametr -XX:+UseLargePages w momencie uruchamiania JVM.

W przypadku serwera aplikacji JBoss najlepiej jest dodać parametr -XX:+UseLargePages w pliku konfiguracyjnym run.conf w miejscu definiowania zmiennej środowiskowej JAVA_OPTS. Po tym kroku można już uruchomić serwer.

Ilość zużytych bloków pamięci można sprawdzić przy użyciu komendy:

cat /proc/meminfo | grep -i pages

Źródła